No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Chris Lahey <clahey@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "e-util/e-util.h"
31
32 #include "e-table-subset-variable.h"
33
34 #define ETSSV_CLASS(e) (E_TABLE_SUBSET_VARIABLE_GET_CLASS (e))
35
36 /* workaround for avoiding API breakage */
37 #define etssv_get_type e_table_subset_variable_get_type
38 G_DEFINE_TYPE (ETableSubsetVariable, etssv, E_TYPE_TABLE_SUBSET)
39
40 #define INCREMENT_AMOUNT 10
41
42 static void
43 etssv_add (ETableSubsetVariable *etssv,
44 gint row)
45 {
46 ETableModel *etm = E_TABLE_MODEL (etssv);
47 ETableSubset *etss = E_TABLE_SUBSET (etssv);
48
49 e_table_model_pre_change (etm);
50
51 if (etss->n_map + 1 > etssv->n_vals_allocated) {
52 etssv->n_vals_allocated += INCREMENT_AMOUNT;
53 etss->map_table = g_realloc (
54 etss->map_table,
55 etssv->n_vals_allocated * sizeof (gint));
56 }
57
58 etss->map_table[etss->n_map++] = row;
59
60 e_table_model_row_inserted (etm, etss->n_map - 1);
61 }
62
63 static void
64 etssv_add_array (ETableSubsetVariable *etssv,
65 const gint *array,
66 gint count)
67 {
68 ETableModel *etm = E_TABLE_MODEL (etssv);
69 ETableSubset *etss = E_TABLE_SUBSET (etssv);
70 gint i;
71
72 e_table_model_pre_change (etm);
73
74 if (etss->n_map + count > etssv->n_vals_allocated) {
75 etssv->n_vals_allocated += MAX (INCREMENT_AMOUNT, count);
76 etss->map_table = g_realloc (
77 etss->map_table,
78 etssv->n_vals_allocated * sizeof (gint));
79 }
80 for (i = 0; i < count; i++)
81 etss->map_table[etss->n_map++] = array[i];
82
83 e_table_model_changed (etm);
84 }
85
86 static void
87 etssv_add_all (ETableSubsetVariable *etssv)
88 {
89 ETableModel *etm = E_TABLE_MODEL (etssv);
90 ETableSubset *etss = E_TABLE_SUBSET (etssv);
91 gint rows;
92 gint i;
93
94 e_table_model_pre_change (etm);
95
96 rows = e_table_model_row_count (etss->source);
97 if (etss->n_map + rows > etssv->n_vals_allocated) {
98 etssv->n_vals_allocated += MAX (INCREMENT_AMOUNT, rows);
99 etss->map_table = g_realloc (
100 etss->map_table,
101 etssv->n_vals_allocated * sizeof (gint));
102 }
103 for (i = 0; i < rows; i++)
104 etss->map_table[etss->n_map++] = i;
105
106 e_table_model_changed (etm);
107 }
108
109 static gboolean
110 etssv_remove (ETableSubsetVariable *etssv,
111 gint row)
112 {
113 ETableModel *etm = E_TABLE_MODEL (etssv);
114 ETableSubset *etss = E_TABLE_SUBSET (etssv);
115 gint i;
116
117 for (i = 0; i < etss->n_map; i++) {
118 if (etss->map_table[i] == row) {
119 e_table_model_pre_change (etm);
120 memmove (
121 etss->map_table + i,
122 etss->map_table + i + 1,
123 (etss->n_map - i - 1) * sizeof (gint));
124 etss->n_map--;
125
126 e_table_model_row_deleted (etm, i);
127 return TRUE;
128 }
129 }
130 return FALSE;
131 }
132
133 static void
134 etssv_class_init (ETableSubsetVariableClass *class)
135 {
136 class->add = etssv_add;
137 class->add_array = etssv_add_array;
138 class->add_all = etssv_add_all;
139 class->remove = etssv_remove;
140 }
141
142 static void
143 etssv_init (ETableSubsetVariable *etssv)
144 {
145 /* nothing to do */
146 }
147
148 ETableModel *
149 e_table_subset_variable_construct (ETableSubsetVariable *etssv,
150 ETableModel *source)
151 {
152 if (e_table_subset_construct (E_TABLE_SUBSET (etssv), source, 1) == NULL)
153 return NULL;
154 E_TABLE_SUBSET (etssv)->n_map = 0;
155
156 return E_TABLE_MODEL (etssv);
157 }
158
159 ETableModel *
160 e_table_subset_variable_new (ETableModel *source)
161 {
162 ETableSubsetVariable *etssv = g_object_new (E_TYPE_TABLE_SUBSET_VARIABLE, NULL);
163
164 if (e_table_subset_variable_construct (etssv, source) == NULL) {
165 g_object_unref (etssv);
166 return NULL;
167 }
168
169 return (ETableModel *) etssv;
170 }
171
172 void
173 e_table_subset_variable_add (ETableSubsetVariable *etssv,
174 gint row)
175 {
176 g_return_if_fail (etssv != NULL);
177 g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv));
178
179 if (ETSSV_CLASS (etssv)->add)
180 ETSSV_CLASS (etssv)->add (etssv, row);
181 }
182
183 void
184 e_table_subset_variable_add_array (ETableSubsetVariable *etssv,
185 const gint *array,
186 gint count)
187 {
188 g_return_if_fail (etssv != NULL);
189 g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv));
190
191 if (ETSSV_CLASS (etssv)->add_array)
192 ETSSV_CLASS (etssv)->add_array (etssv, array, count);
193 }
194
195 void
196 e_table_subset_variable_add_all (ETableSubsetVariable *etssv)
197 {
198 g_return_if_fail (etssv != NULL);
199 g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv));
200
201 if (ETSSV_CLASS (etssv)->add_all)
202 ETSSV_CLASS (etssv)->add_all (etssv);
203 }
204
205 gboolean
206 e_table_subset_variable_remove (ETableSubsetVariable *etssv,
207 gint row)
208 {
209 g_return_val_if_fail (etssv != NULL, FALSE);
210 g_return_val_if_fail (E_IS_TABLE_SUBSET_VARIABLE (etssv), FALSE);
211
212 if (ETSSV_CLASS (etssv)->remove)
213 return ETSSV_CLASS (etssv)->remove (etssv, row);
214 else
215 return FALSE;
216 }
217
218 void
219 e_table_subset_variable_clear (ETableSubsetVariable *etssv)
220 {
221 ETableModel *etm = E_TABLE_MODEL (etssv);
222 ETableSubset *etss = E_TABLE_SUBSET (etssv);
223
224 e_table_model_pre_change (etm);
225 etss->n_map = 0;
226 g_free (etss->map_table);
227 etss->map_table = (gint *) g_new (guint, 1);
228 etssv->n_vals_allocated = 1;
229
230 e_table_model_changed (etm);
231 }
232
233 void
234 e_table_subset_variable_increment (ETableSubsetVariable *etssv,
235 gint position,
236 gint amount)
237 {
238 gint i;
239 ETableSubset *etss = E_TABLE_SUBSET (etssv);
240 for (i = 0; i < etss->n_map; i++) {
241 if (etss->map_table[i] >= position)
242 etss->map_table[i] += amount;
243 }
244 }
245
246 void
247 e_table_subset_variable_decrement (ETableSubsetVariable *etssv,
248 gint position,
249 gint amount)
250 {
251 gint i;
252 ETableSubset *etss = E_TABLE_SUBSET (etssv);
253 for (i = 0; i < etss->n_map; i++) {
254 if (etss->map_table[i] >= position)
255 etss->map_table[i] -= amount;
256 }
257 }
258
259 void
260 e_table_subset_variable_set_allocation (ETableSubsetVariable *etssv,
261 gint total)
262 {
263 ETableSubset *etss = E_TABLE_SUBSET (etssv);
264 if (total <= 0)
265 total = 1;
266 if (total > etss->n_map) {
267 etss->map_table = g_realloc (etss->map_table, total * sizeof (gint));
268 }
269 }