~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to src/go-data-slicer-field.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-22 13:37:20 UTC
  • mfrom: (1.1.20 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090622133720-rtdazsiz2lx5q8l7
Tags: 1.9.9-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure
    o debian/gnumeric-plugins-extra.install: don't install the psiconv
      plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * go-data-slicer-field.h : The definition of a content for a data slicer
 
4
 *
 
5
 * Copyright (C) 2008 Jody Goldberg (jody@gnome.org)
 
6
 *
 
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.
 
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-field-impl.h"
 
24
#include "go-data-slicer-impl.h"
 
25
#include "go-data-cache-field.h"
 
26
#include "go-data-cache.h"
 
27
 
 
28
#include <gsf/gsf-impl-utils.h>
 
29
#include <glib/gi18n-lib.h>
 
30
#include <string.h>
 
31
 
 
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))
 
35
 
 
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
 
43
};
 
44
 
 
45
static void
 
46
go_data_slicer_field_init (GODataSlicerField *dsf)
 
47
{
 
48
        int i;
 
49
 
 
50
        dsf->ds = NULL;
 
51
        dsf->name = NULL;
 
52
        dsf->indx = -1;
 
53
        dsf->data_cache_field_indx = -1;
 
54
        dsf->aggregations = 0;
 
55
 
 
56
        for (i = GDS_FIELD_TYPE_MAX ; i-- > GDS_FIELD_TYPE_UNSET ; )
 
57
                dsf->field_type_pos[i] = -1;
 
58
}
 
59
 
 
60
static GObjectClass *parent_klass;
 
61
static void
 
62
go_data_slicer_field_finalize (GObject *obj)
 
63
{
 
64
        GODataSlicerField *dsf = (GODataSlicerField *)obj;
 
65
        go_string_unref (dsf->name); dsf->name = NULL;
 
66
        (parent_klass->finalize) (obj);
 
67
}
 
68
 
 
69
static void
 
70
go_data_slicer_field_set_property (GObject *obj, guint property_id,
 
71
                                   GValue const *value, GParamSpec *pspec)
 
72
{
 
73
        GODataSlicerField *dsf = (GODataSlicerField *)obj;
 
74
 
 
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;
 
81
        default:
 
82
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
 
83
        }
 
84
}
 
85
 
 
86
static void
 
87
go_data_slicer_field_get_property (GObject *obj, guint property_id,
 
88
                                   GValue *value, GParamSpec *pspec)
 
89
{
 
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;
 
98
        default:
 
99
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
 
100
        }
 
101
}
 
102
 
 
103
static void
 
104
go_data_slicer_field_class_init (GODataSlicerFieldClass *klass)
 
105
{
 
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;
 
110
 
 
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",
 
120
                        -1, G_MAXINT, -1,
 
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",
 
125
                        -1, G_MAXINT, -1,
 
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",
 
130
                        0, ~0, 0,
 
131
                        GSF_PARAM_STATIC | G_PARAM_READWRITE));
 
132
 
 
133
        parent_klass = g_type_class_peek_parent (klass);
 
134
}
 
135
 
 
136
GSF_CLASS (GODataSlicerField, go_data_slicer_field,
 
137
           go_data_slicer_field_class_init, go_data_slicer_field_init,
 
138
           G_TYPE_OBJECT)
 
139
 
 
140
/**
 
141
 * go_data_slicer_field_get_cache_field :
 
142
 * @dsf : #GODataSlicerField const
 
143
 *
 
144
 * Returns : the underlying cache field
 
145
 **/
 
146
GODataCacheField *
 
147
go_data_slicer_field_get_cache_field (GODataSlicerField const *dsf)
 
148
{
 
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);
 
152
}
 
153
 
 
154
/**
 
155
 * go_data_slicer_field_get_name :
 
156
 * @dsf : #GODataSlicerField const
 
157
 *
 
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.
 
161
 *
 
162
 * Returns: the name of the field.
 
163
 **/
 
164
GOString *
 
165
go_data_slicer_field_get_name (GODataSlicerField const *dsf)
 
166
{
 
167
        g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), NULL);
 
168
        if (dsf->name)
 
169
                return dsf->name;
 
170
        return go_data_cache_field_get_name (
 
171
                go_data_slicer_field_get_cache_field (dsf));
 
172
}
 
173
 
 
174
int
 
175
go_data_slicer_field_get_field_type_pos (GODataSlicerField const *dsf,
 
176
                                         GODataSlicerFieldType field_type)
 
177
{
 
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];
 
182
}
 
183
 
 
184
/**
 
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
 
189
 *
 
190
 * Make @dsf a @field_type, and move it to position @pos other @field_type's
 
191
 * in the slicer.
 
192
 **/
 
193
void
 
194
go_data_slicer_field_set_field_type_pos (GODataSlicerField *dsf,
 
195
                                         GODataSlicerFieldType field_type,
 
196
                                         int pos)
 
197
{
 
198
        GArray *headers;
 
199
        int cur_pos, i;
 
200
 
 
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);
 
204
 
 
205
        headers = dsf->ds->fields [field_type];
 
206
        if (pos < 0) pos = -1;
 
207
        else if (pos >= (int)headers->len) pos = headers->len;
 
208
 
 
209
        cur_pos = dsf->field_type_pos[field_type];
 
210
        if (pos == cur_pos) return;
 
211
 
 
212
        /* Remove it */
 
213
        if (cur_pos >= 0) {
 
214
                g_return_if_fail (cur_pos < (int)headers->len);
 
215
                g_return_if_fail (g_array_index (headers, int, cur_pos) == dsf->indx);
 
216
 
 
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]);
 
224
                        else
 
225
                                g_warning ("inconsistent field_type_pos");
 
226
                }
 
227
 
 
228
                /* adjust target index if our removal would change it */
 
229
                if (cur_pos < pos) pos--;
 
230
        }
 
231
 
 
232
        /* put it back in the right place */
 
233
        if (pos >= 0) {
 
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]);
 
241
                                else
 
242
                                        g_warning ("inconsistent field_type_pos");
 
243
                        }
 
244
                } else
 
245
                        g_array_append_val (headers, dsf->indx);
 
246
        }
 
247
        dsf->field_type_pos[field_type] = pos;
 
248
}
 
249