1 /*
2  * go-data-slicer.h : The definition of a content for a data slicer
3  *
4  * Copyright (C) 2008 Jody Goldberg (jody@gnome.org)
5  *
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.
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 St, Fifth Floor, Boston, MA  02110-1301
19  * USA
20  */
21 
22 #include <gnumeric-config.h>
23 #include <go-data-slicer-impl.h>
24 #include <go-data-slicer-field-impl.h>
25 #include <go-data-cache.h>
26 
27 #include <gsf/gsf-impl-utils.h>
28 #include <glib/gi18n-lib.h>
29 #include <string.h>
30 
31 #define GO_DATA_SLICER_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), GO_DATA_SLICER_TYPE, GODataSlicerClass))
32 #define IS_GO_DATA_SLICER_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GO_DATA_SLICER_TYPE))
33 #define GO_DATA_SLICER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GO_DATA_SLICER_TYPE, GODataSlicerClass))
34 
35 enum {
36 	PROP_0,
37 	PROP_CACHE,	/* GODataCache * */
38 	PROP_NAME,	/* GOString */
39 };
40 static void
go_data_slicer_init(GODataSlicer * ds)41 go_data_slicer_init (GODataSlicer *ds)
42 {
43 	int i;
44 
45 	ds->cache = NULL;
46 	ds->name  = NULL;
47 	ds->all_fields  = g_ptr_array_new ();
48 	for (i = GDS_FIELD_TYPE_MAX ; --i > GDS_FIELD_TYPE_UNSET ; )
49 		ds->fields[i] = g_array_new (FALSE, FALSE, sizeof (int));
50 }
51 
52 static GObjectClass *parent_klass;
53 static void
go_data_slicer_finalize(GObject * obj)54 go_data_slicer_finalize (GObject *obj)
55 {
56 	GODataSlicer *ds = (GODataSlicer *)obj;
57 	int i;
58 
59 	for (i = GDS_FIELD_TYPE_MAX ; --i > GDS_FIELD_TYPE_UNSET ; ) {
60 		g_array_free (ds->fields[i], TRUE);
61 		ds->fields[i] = NULL;
62 	}
63 
64 	for (i = (int)ds->all_fields->len ; i-- > 0 ; )
65 		g_object_unref (g_ptr_array_index (ds->all_fields, i));
66 	g_ptr_array_free (ds->all_fields, TRUE);
67 	ds->all_fields = NULL;
68 
69 	go_data_slicer_set_cache (ds, NULL);
70 	go_string_unref (ds->name); ds->name   = NULL;
71 
72 	(parent_klass->finalize) (obj);
73 }
74 
75 static void
go_data_slicer_set_property(GObject * obj,guint property_id,GValue const * value,GParamSpec * pspec)76 go_data_slicer_set_property (GObject *obj, guint property_id,
77 				  GValue const *value, GParamSpec *pspec)
78 {
79 	GODataSlicer *ds = (GODataSlicer *)obj;
80 
81 	switch (property_id) {
82 	case PROP_CACHE : go_data_slicer_set_cache (ds, g_value_get_object (value)); break;
83 	case PROP_NAME :  go_string_unref (ds->name); ds->name = g_value_dup_boxed (value); break;
84 	default:
85 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
86 	}
87 }
88 
89 static void
go_data_slicer_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)90 go_data_slicer_get_property (GObject *obj, guint property_id,
91 				    GValue *value, GParamSpec *pspec)
92 {
93 	GODataSlicer const *ds = (GODataSlicer const *)obj;
94 	switch (property_id) {
95 	case PROP_CACHE : g_value_set_object (value, ds->cache); break;
96 	case PROP_NAME  : g_value_set_boxed (value, ds->name); break;
97 	default:
98 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
99 	}
100 }
101 
102 static void
go_data_slicer_class_init(GODataSlicerClass * klass)103 go_data_slicer_class_init (GODataSlicerClass *klass)
104 {
105 	GObjectClass *gobject_class = (GObjectClass *)klass;
106 	gobject_class->set_property	= go_data_slicer_set_property;
107 	gobject_class->get_property	= go_data_slicer_get_property;
108 	gobject_class->finalize		= go_data_slicer_finalize;
109 
110 	g_object_class_install_property (gobject_class, PROP_CACHE,
111 		 g_param_spec_object ("cache", NULL, NULL,
112 			GO_DATA_CACHE_TYPE, GSF_PARAM_STATIC | G_PARAM_READWRITE));
113 	g_object_class_install_property (gobject_class, PROP_NAME,
114 		 g_param_spec_boxed ("name", NULL, NULL, go_string_get_type (),
115 			GSF_PARAM_STATIC | G_PARAM_READWRITE));
116 
117 	parent_klass = g_type_class_peek_parent (klass);
118 }
119 
GSF_CLASS(GODataSlicer,go_data_slicer,go_data_slicer_class_init,go_data_slicer_init,G_TYPE_OBJECT)120 GSF_CLASS (GODataSlicer, go_data_slicer,
121 	   go_data_slicer_class_init, go_data_slicer_init,
122 	   G_TYPE_OBJECT)
123 
124 /**
125  * go_data_slicer_get_cache:
126  * @ds: #GODataSlicer
127  *
128  * Does not add a reference.
129  *
130  * Returns : the #GODataCache associated with @ds
131  **/
132 GODataCache *
133 go_data_slicer_get_cache (GODataSlicer const *ds)
134 {
135 	g_return_val_if_fail (IS_GO_DATA_SLICER (ds), NULL);
136 	return ds->cache;
137 }
138 
139 /**
140  * go_data_slicer_set_cache:
141  * @ds: #GODataSlicer
142  * @cache: #GODataCache
143  *
144  * Assign @cache to @ds, and adds a reference to @cache
145  **/
146 void
go_data_slicer_set_cache(GODataSlicer * ds,GODataCache * cache)147 go_data_slicer_set_cache (GODataSlicer *ds, GODataCache *cache)
148 {
149 	g_return_if_fail (IS_GO_DATA_SLICER (ds));
150 
151 	if (NULL != cache)
152 		g_object_ref (cache);
153 	if (NULL != ds->cache)
154 		g_object_unref (ds->cache);
155 	ds->cache = cache;
156 }
157 
158 void
go_data_slicer_add_field(GODataSlicer * ds,GODataSlicerField * field)159 go_data_slicer_add_field (GODataSlicer *ds, GODataSlicerField *field)
160 {
161 	g_return_if_fail (IS_GO_DATA_SLICER (ds));
162 	g_return_if_fail (IS_GO_DATA_SLICER_FIELD (field));
163 	g_return_if_fail (field->indx < 0);
164 	g_return_if_fail (field->ds == NULL);
165 
166 	field->indx = ds->all_fields->len;
167 	field->ds   = ds;
168 	g_ptr_array_add (ds->all_fields, field);
169 }
170 
171 unsigned int
go_data_slicer_num_fields(GODataSlicer const * ds)172 go_data_slicer_num_fields (GODataSlicer const *ds)
173 {
174 	g_return_val_if_fail (IS_GO_DATA_SLICER (ds), 0);
175 	return ds->all_fields->len;
176 }
177 
178 GODataSlicerField *
go_data_slicer_get_field(GODataSlicer const * ds,unsigned int field_index)179 go_data_slicer_get_field (GODataSlicer const *ds, unsigned int field_index)
180 {
181 	g_return_val_if_fail (IS_GO_DATA_SLICER (ds), NULL);
182 	g_return_val_if_fail (field_index < ds->all_fields->len, NULL);
183 	return g_ptr_array_index (ds->all_fields, field_index);
184 }
185 
186