1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
* go-data-slicer-field.h : The definition of a content for a data slicer
5
* Copyright (C) 2008 Jody Goldberg (jody@gnome.org)
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of version 2 of the GNU General Public
9
* License as published by the Free Software Foundation.
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 = GDS_FIELD_TYPE_MAX ; i-- > GDS_FIELD_TYPE_UNSET ; )
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;
65
go_string_unref (dsf->name); dsf->name = NULL;
66
(parent_klass->finalize) (obj);
70
go_data_slicer_field_set_property (GObject *obj, guint property_id,
71
GValue const *value, GParamSpec *pspec)
73
GODataSlicerField *dsf = (GODataSlicerField *)obj;
75
switch (property_id) {
76
/* we do not hold a ref */
77
case PROP_SLICER : dsf->ds = g_value_get_object (value); break;
78
case PROP_NAME : go_string_unref (dsf->name); dsf->name = g_value_dup_boxed (value); break;
79
case PROP_DATA_CACHE_FIELD_INDEX : dsf->data_cache_field_indx = g_value_get_int (value); break;
80
case PROP_AGGREGATIONS : dsf->aggregations = g_value_get_uint (value); break;
82
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
87
go_data_slicer_field_get_property (GObject *obj, guint property_id,
88
GValue *value, GParamSpec *pspec)
90
GODataSlicerField const *dsf = (GODataSlicerField const *)obj;
91
switch (property_id) {
92
case PROP_SLICER : g_value_set_object (value, dsf->ds); break;
93
case PROP_NAME : g_value_set_boxed (value, dsf->name); break; /* actual name, do not fall back to cache */
94
case PROP_INDEX : g_value_set_int (value, dsf->indx); break;
95
case PROP_DATA_CACHE_FIELD_INDEX :
96
g_value_set_int (value, dsf->data_cache_field_indx); break;
97
case PROP_AGGREGATIONS : g_value_set_uint (value, dsf->aggregations); break;
99
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
104
go_data_slicer_field_class_init (GODataSlicerFieldClass *klass)
106
GObjectClass *gobject_class = (GObjectClass *)klass;
107
gobject_class->finalize = go_data_slicer_field_finalize;
108
gobject_class->set_property = go_data_slicer_field_set_property;
109
gobject_class->get_property = go_data_slicer_field_get_property;
111
g_object_class_install_property (gobject_class, PROP_SLICER,
112
g_param_spec_object ("slicer", NULL, NULL,
113
GO_DATA_SLICER_TYPE, GSF_PARAM_STATIC | G_PARAM_READWRITE));
114
g_object_class_install_property (gobject_class, PROP_NAME,
115
g_param_spec_boxed ("name", NULL, NULL, go_string_get_type (),
116
GSF_PARAM_STATIC | G_PARAM_READWRITE));
117
g_object_class_install_property (gobject_class, PROP_INDEX,
118
g_param_spec_int ("index", NULL,
119
"Index of the field within the GODataSlicer",
121
GSF_PARAM_STATIC | G_PARAM_READABLE));
122
g_object_class_install_property (gobject_class, PROP_DATA_CACHE_FIELD_INDEX,
123
g_param_spec_int ("data-cache-field-index", NULL,
124
"Index of the underlying GODataCacheField",
126
GSF_PARAM_STATIC | G_PARAM_READWRITE));
127
g_object_class_install_property (gobject_class, PROP_AGGREGATIONS,
128
g_param_spec_uint ("aggregations", NULL,
129
"bitwise OR of the set of aggregations",
131
GSF_PARAM_STATIC | G_PARAM_READWRITE));
133
parent_klass = g_type_class_peek_parent (klass);
136
GSF_CLASS (GODataSlicerField, go_data_slicer_field,
137
go_data_slicer_field_class_init, go_data_slicer_field_init,
141
* go_data_slicer_field_get_cache_field :
142
* @dsf : #GODataSlicerField const
144
* Returns : the underlying cache field
147
go_data_slicer_field_get_cache_field (GODataSlicerField const *dsf)
149
g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), NULL);
150
return go_data_cache_get_field (go_data_slicer_get_cache (dsf->ds),
151
dsf->data_cache_field_indx);
155
* go_data_slicer_field_get_name :
156
* @dsf : #GODataSlicerField const
158
* If @dsf has a name return that, otherwise default to the name of the
159
* underlying cache field. If there is a need (e.g. for export) to get the
160
* exact name without the default, use the properties.
162
* Returns: the name of the field.
165
go_data_slicer_field_get_name (GODataSlicerField const *dsf)
167
g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), NULL);
170
return go_data_cache_field_get_name (
171
go_data_slicer_field_get_cache_field (dsf));
175
go_data_slicer_field_get_field_type_pos (GODataSlicerField const *dsf,
176
GODataSlicerFieldType field_type)
178
g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), -1);
179
g_return_val_if_fail (field_type > GDS_FIELD_TYPE_UNSET &&
180
field_type < GDS_FIELD_TYPE_MAX, -1);
181
return dsf->field_type_pos[field_type];
185
* go_data_slicer_field_set_field_type_pos :
186
* @dsf : #GODataSlicerField
187
* @field_type : #GODataSlicerFieldType
188
* @pos : >= len => append, else move ahead of @pos, -1 removes
190
* Make @dsf a @field_type, and move it to position @pos other @field_type's
194
go_data_slicer_field_set_field_type_pos (GODataSlicerField *dsf,
195
GODataSlicerFieldType field_type,
201
g_return_if_fail (IS_GO_DATA_SLICER_FIELD (dsf));
202
g_return_if_fail (field_type > GDS_FIELD_TYPE_UNSET &&
203
field_type < GDS_FIELD_TYPE_MAX);
205
headers = dsf->ds->fields [field_type];
206
if (pos < 0) pos = -1;
207
else if (pos >= (int)headers->len) pos = headers->len;
209
cur_pos = dsf->field_type_pos[field_type];
210
if (pos == cur_pos) return;
214
g_return_if_fail (cur_pos < (int)headers->len);
215
g_return_if_fail (g_array_index (headers, int, cur_pos) == dsf->indx);
217
g_array_remove_index (headers, cur_pos);
218
dsf->field_type_pos[field_type] = -1;
219
for (i = cur_pos; i < (int)headers->len ; i++) {
220
GODataSlicerField *other = go_data_slicer_get_field (dsf->ds,
221
g_array_index (headers, int, i));
222
if (NULL != other && other->field_type_pos[field_type] == (i+1))
223
--(other->field_type_pos[field_type]);
225
g_warning ("inconsistent field_type_pos");
228
/* adjust target index if our removal would change it */
229
if (cur_pos < pos) pos--;
232
/* put it back in the right place */
234
if (pos < (int)headers->len) {
235
g_array_insert_val (headers, pos, dsf->indx);
236
for (i = pos; ++i < (int)headers->len ; ) {
237
GODataSlicerField *other = go_data_slicer_get_field (dsf->ds,
238
g_array_index (headers, int, i));
239
if (NULL != other && other->field_type_pos[field_type] == (i-1))
240
++(other->field_type_pos[field_type]);
242
g_warning ("inconsistent field_type_pos");
245
g_array_append_val (headers, dsf->indx);
247
dsf->field_type_pos[field_type] = pos;