Fixed some memory leaks in GUI.
[pspp-builds.git] / lib / gtksheet / gsheetmodel.c
1 /* GSheetModel --- an abstract model for the GSheet widget.
2  * Copyright (C) 2006 Free Software Foundation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include <glib.h>
20 #include "gsheetmodel.h"
21 #include "gtkextra-marshal.h"
22
23 enum {
24   RANGE_CHANGED,
25   ROWS_INSERTED,
26   ROWS_DELETED,
27   LAST_SIGNAL
28 };
29
30 static guint sheet_model_signals[LAST_SIGNAL] = { 0 };
31
32
33 static void      g_sheet_model_base_init   (gpointer           g_class);
34
35
36 inline GType
37 g_sheet_model_get_type (void)
38 {
39   static GType sheet_model_type = 0;
40
41   if (! sheet_model_type)
42     {
43       static const GTypeInfo sheet_model_info =
44       {
45         sizeof (GSheetModelIface), /* class_size */
46         g_sheet_model_base_init,   /* base_init */
47         NULL,           /* base_finalize */
48         NULL,
49         NULL,           /* class_finalize */
50         NULL,           /* class_data */
51         0,
52         0,              /* n_preallocs */
53         NULL
54       };
55
56       sheet_model_type =
57         g_type_register_static (G_TYPE_INTERFACE, "GSheetModel",
58                                 &sheet_model_info, 0);
59
60       g_type_interface_add_prerequisite (sheet_model_type, G_TYPE_OBJECT);
61     }
62
63   return sheet_model_type;
64 }
65
66 static void
67 g_sheet_model_base_init (gpointer g_class)
68 {
69   static gboolean initialized = FALSE;
70
71   if (! initialized)
72     {
73       sheet_model_signals[RANGE_CHANGED] =
74         g_signal_new ("range_changed",
75                       G_TYPE_SHEET_MODEL,
76                       G_SIGNAL_RUN_LAST,
77                       G_STRUCT_OFFSET (GSheetModelIface, range_changed),
78                       NULL, NULL,
79                       gtkextra_VOID__INT_INT_INT_INT,
80                       G_TYPE_NONE, 4,
81                       G_TYPE_INT,
82                       G_TYPE_INT,
83                       G_TYPE_INT,
84                       G_TYPE_INT);
85
86
87
88       sheet_model_signals[ROWS_INSERTED] =
89         g_signal_new ("rows_inserted",
90                       G_TYPE_SHEET_MODEL,
91                       G_SIGNAL_RUN_LAST,
92                       G_STRUCT_OFFSET (GSheetModelIface, rows_inserted),
93                       NULL, NULL,
94                       gtkextra_VOID__INT_INT,
95                       G_TYPE_NONE, 2,
96                       G_TYPE_INT,
97                       G_TYPE_INT);
98
99
100       sheet_model_signals[ROWS_DELETED] =
101         g_signal_new ("rows_deleted",
102                       G_TYPE_SHEET_MODEL,
103                       G_SIGNAL_RUN_LAST,
104                       G_STRUCT_OFFSET (GSheetModelIface, rows_deleted),
105                       NULL, NULL,
106                       gtkextra_VOID__INT_INT,
107                       G_TYPE_NONE, 2,
108                       G_TYPE_INT,
109                       G_TYPE_INT);
110
111                     
112       initialized = TRUE;
113     }
114 }
115
116
117 /**
118  * g_sheet_model_free_strings
119  * @sheet_model: A #GSheetModel
120  * 
121  * Returns: True if strings obtained with get_string should be freed by the 
122  * sheet when no longer required.
123  **/
124 inline  gboolean 
125 g_sheet_model_free_strings (const GSheetModel *sheet_model)
126 {
127   g_return_val_if_fail (G_IS_SHEET_MODEL (sheet_model), FALSE);
128
129   return G_SHEET_MODEL_GET_IFACE (sheet_model)->free_strings;
130 }
131
132
133 /**
134  * g_sheet_model_get_string:
135  * @sheet_model: A #GSheetModel
136  * @row: The row of the cell to be retrieved.
137  * @column: The column of the cell to be retrieved.
138  * 
139  * Retrieves the datum at location ROW, COLUMN in the form of a string.
140  * Returns: The string representation of the datum, or NULL on error.
141  **/
142 inline gchar *
143 g_sheet_model_get_string (const GSheetModel *sheet_model, 
144                           gint row, gint column)
145 {
146   g_return_val_if_fail (G_IS_SHEET_MODEL (sheet_model), 0);
147
148   g_assert (G_SHEET_MODEL_GET_IFACE (sheet_model)->get_string);
149   
150   return (G_SHEET_MODEL_GET_IFACE (sheet_model)->get_string) (sheet_model, row, column);
151 }
152
153 /**
154  * g_sheet_model_set_string
155  * @sheet_model: A #GSheetModel
156  * @text: The text describing the datum to be set.
157  * @row: The row of the cell to be cleared.
158  * @column: The column of the cell to be cleared.
159  * 
160  * Sets the datum at a location from a string.
161  * Returns: TRUE if the datum was changed, FALSE otherwise.
162  **/
163 gboolean
164 g_sheet_model_set_string      (GSheetModel *sheet_model, 
165                                  const gchar *text, 
166                                  gint row, gint column)
167 {
168   g_return_val_if_fail (G_IS_SHEET_MODEL (sheet_model), FALSE);
169
170   g_assert (G_SHEET_MODEL_GET_IFACE (sheet_model)->set_string);
171
172   return G_SHEET_MODEL_GET_IFACE (sheet_model)->set_string (sheet_model, 
173                                                             text, row, column);
174 }
175
176
177
178 /**
179  * g_sheet_model_datum_clear:
180  * @sheet_model: A #GSheetModel
181  * @row: The row of the cell to be cleared.
182  * @column: The column of the cell to be cleared.
183  * 
184  * Called when the datum at a location is to be cleared.
185  * Returns: TRUE if the datum was cleared, FALSE otherwise.
186  **/
187 gboolean
188 g_sheet_model_datum_clear    (GSheetModel *sheet_model, 
189                                 gint row, gint column)
190 {
191   g_return_val_if_fail (G_IS_SHEET_MODEL (sheet_model), FALSE);
192
193   g_assert (G_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum);
194
195   return G_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum (sheet_model, 
196                                                                 row, column);
197 }
198
199
200 /**
201  * g_sheet_model_range_changed:
202  * @sheet_model: A #GSheetModel
203  * @range: The #GSheetRange range of cells which have changed.
204  * 
205  * Emits the "range_changed" signal on @sheet_model.
206  **/
207 void
208 g_sheet_model_range_changed (GSheetModel *sheet_model,
209                                gint row0, gint col0,
210                                gint rowi, gint coli)
211 {
212   g_return_if_fail (G_IS_SHEET_MODEL (sheet_model));
213
214   g_signal_emit (sheet_model, sheet_model_signals[RANGE_CHANGED], 0, 
215                  row0, col0, rowi, coli);
216 }
217
218
219
220
221 /**
222  * g_sheet_model_rows_inserted:
223  * @sheet_model: A #GSheetModel
224  * @row: The row before which the new rows should be inserted.
225  * @n_rows: The number of rows to insert.
226  * 
227  * Emits the "rows_inserted" signal on @sheet_model.
228  **/
229 void
230 g_sheet_model_rows_inserted (GSheetModel *sheet_model,
231                                gint row, gint n_rows)
232 {
233   g_return_if_fail (G_IS_SHEET_MODEL (sheet_model));
234
235   g_signal_emit (sheet_model, sheet_model_signals[ROWS_INSERTED], 0, 
236                  row, n_rows);
237 }
238
239
240
241
242 /**
243  * g_sheet_model_rows_deleted:
244  * @sheet_model: A #GSheetModel
245  * @row: The first row to be deleted.
246  * @n_rows: The number of rows to delete.
247  * 
248  * Emits the "rows_deleted" signal on @sheet_model.
249  **/
250 void
251 g_sheet_model_rows_deleted (GSheetModel *sheet_model,
252                                gint row, gint n_rows)
253 {
254   g_return_if_fail (G_IS_SHEET_MODEL (sheet_model));
255
256   g_signal_emit (sheet_model, sheet_model_signals[ROWS_DELETED], 0, 
257                  row, n_rows);
258 }
259
260
261
262
263 /**
264  * g_sheet_model_is_editable:
265  * @sheet_model: A #GSheetModel
266  * @row: The row 
267  * @column: The column
268  * 
269  * Returns: TRUE if the cell is editable, FALSE otherwise
270  **/
271 inline gboolean 
272 g_sheet_model_is_editable (const GSheetModel *model, 
273                              gint row, gint column)
274 {
275   g_return_val_if_fail (G_IS_SHEET_MODEL (model), TRUE);
276
277   if ( ! G_SHEET_MODEL_GET_IFACE (model)->is_editable )
278     return TRUE;
279
280   return G_SHEET_MODEL_GET_IFACE (model)->is_editable (model, 
281                                                           row, column);
282 }
283
284 /**
285  * g_sheet_model_is_visible:
286  * @sheet_model: A #GSheetModel
287  * @row: The row 
288  * @column: The column
289  * 
290  * Returns: TRUE if the cell is visible, FALSE otherwise
291  **/
292 inline gboolean 
293 g_sheet_model_is_visible (const GSheetModel *model, 
294                           gint row, gint column)
295 {
296   g_return_val_if_fail (G_IS_SHEET_MODEL (model), TRUE);
297
298   if ( ! G_SHEET_MODEL_GET_IFACE (model)->is_visible )
299     return TRUE;
300
301   return G_SHEET_MODEL_GET_IFACE (model)->is_visible (model, 
302                                                         row, column);
303 }
304
305
306 /**
307  * g_sheet_model_get_foreground:
308  * @sheet_model: A #GSheetModel
309  * @row: The row 
310  * @column: The column
311  *
312  * Returns the foreground colour of the cell at @row, @column
313  * Returns: the foreground colour, or NULL on error.
314  **/
315 inline const GdkColor *
316 g_sheet_model_get_foreground (const GSheetModel *model, 
317                                 gint row, gint column)
318 {
319   g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
320
321   if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_foreground )
322     return NULL;
323
324   return G_SHEET_MODEL_GET_IFACE (model)->get_foreground (model, 
325                                                             row, column);
326 }
327
328 /**
329  * g_sheet_model_get_background:
330  * @sheet_model: A #GSheetModel
331  * @row: The row 
332  * @column: The column
333  *
334  * Returns the background colour of the cell at @row, @column
335  * Returns: the background colour, or NULL on error.
336  **/
337 inline const GdkColor *
338 g_sheet_model_get_background (const GSheetModel *model, 
339                                 gint row, gint column)
340 {
341   g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
342
343   if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_background )
344     return NULL;
345
346   return G_SHEET_MODEL_GET_IFACE (model)->get_background (model, 
347                                                             row, column);
348 }
349
350 /**
351  * g_sheet_model_get_justification:
352  * @sheet_model: A #GSheetModel
353  * @row: The row 
354  * @column: The column
355  *
356  * Returns the justification of the cell at @row, @column
357  * Returns: the justification, or NULL on error.
358  **/
359 inline const GtkJustification *
360 g_sheet_model_get_justification (const GSheetModel *model, 
361                                    gint row, gint column)
362 {
363   g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
364
365   if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_justification)
366     return NULL;
367
368   return G_SHEET_MODEL_GET_IFACE (model)->get_justification (model, 
369                                                                row, column);
370 }
371
372 /**
373  * g_sheet_model_get_font_desc:
374  * @sheet_model: A #GSheetModel
375  * @row: The row 
376  * @column: The column
377  *
378  * Returns the font description of the cell at @row, @column
379  * Returns: the font description, or NULL on error.
380  **/
381 inline const PangoFontDescription *
382 g_sheet_model_get_font_desc(const GSheetModel *model,
383                               gint row, gint column)
384 {
385   g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
386   if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_font_desc)
387     return NULL;
388
389   return G_SHEET_MODEL_GET_IFACE (model)->get_font_desc (model, 
390                                                            row, column);
391 }
392
393 /**
394  * g_sheet_model_get_cell_border:
395  * @sheet_model: A #GSheetModel
396  * @row: The row 
397  * @column: The column
398  *
399  * Returns the cell border of the cell at @row, @column
400  * Returns: the cell border, or NULL on error.
401  **/
402 inline const GtkSheetCellBorder * 
403 g_sheet_model_get_cell_border (const GSheetModel *model, 
404                                  gint row, gint column)
405 {
406   g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
407   if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_cell_border)
408     return NULL;
409
410   return G_SHEET_MODEL_GET_IFACE (model)->get_cell_border (model, 
411                                                            row, column);
412 }
413
414
415