Plugged memory leaks in GUI, and converted most of the strings to UTF8, so that
[pspp-builds.git] / lib / gtksheet / gsheet-row-iface.c
1 /* GSheetRow --- an abstract model of the row geometry of a 
2  * GSheet widget.
3  * Copyright (C) 2006 Free Software Foundation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 #include <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <glib/gprintf.h>
23 #include <gobject/gvaluecollector.h>
24 #include "gsheet-row-iface.h"
25 #include "gtkextra-marshal.h"
26
27
28 enum {
29   ROWS_CHANGED,
30   LAST_SIGNAL
31 };
32
33 static guint sheet_row_signals[LAST_SIGNAL];
34
35
36
37 static void      g_sheet_row_base_init   (gpointer g_class);
38
39
40 GType
41 g_sheet_row_get_type (void)
42 {
43   static GType sheet_row_type = 0;
44
45   if (! sheet_row_type)
46     {
47       static const GTypeInfo sheet_row_info =
48
49       {
50         sizeof (GSheetRowIface), /* class_size */
51         g_sheet_row_base_init,   /* base_init */
52         NULL,           /* base_finalize */
53         NULL,
54         NULL,           /* class_finalize */
55         NULL,           /* class_data */
56         0,
57         0,              /* n_preallocs */
58         NULL
59       };
60
61       sheet_row_type =
62         g_type_register_static (G_TYPE_INTERFACE, "GSheetRow",
63                                 &sheet_row_info, 0);
64
65       g_type_interface_add_prerequisite (sheet_row_type, G_TYPE_OBJECT);
66     }
67
68   return sheet_row_type;
69 }
70
71
72 static GtkSheetButton default_button;
73
74 static void
75 g_sheet_row_base_init (gpointer g_class)
76 {
77   static gboolean initialized = FALSE;
78
79   if (! initialized)
80     {
81
82       sheet_row_signals[ROWS_CHANGED] =
83         g_signal_new ("rows_changed",
84                       G_TYPE_SHEET_ROW,
85                       G_SIGNAL_RUN_LAST,
86                       G_STRUCT_OFFSET (GSheetRowIface, rows_changed),
87                       NULL, NULL,
88                       gtkextra_VOID__INT_INT,
89                       G_TYPE_NONE, 2,
90                       G_TYPE_INT,
91                       G_TYPE_INT);
92
93
94       default_button.state = GTK_STATE_NORMAL;
95       default_button.label = NULL;
96       default_button.label_visible = TRUE;
97       default_button.child = NULL;
98       default_button.justification = GTK_JUSTIFY_FILL;
99
100       initialized = TRUE;
101     }
102 }
103
104 void  
105 g_sheet_row_set_height (GSheetRow *row_geo,
106                                 gint row, gint size, const GtkSheet *sheet)
107 {
108   g_return_if_fail (G_IS_SHEET_ROW (row_geo));
109
110   if ((G_SHEET_ROW_GET_IFACE (row_geo)->set_height) ) 
111     (G_SHEET_ROW_GET_IFACE (row_geo)->set_height) (row_geo, row, 
112                                                         size, sheet);
113 }
114
115
116 gint 
117 g_sheet_row_get_height     (const GSheetRow *row_geo, 
118                                     gint row, const GtkSheet *sheet)
119 {
120   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), -1);
121
122   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_height);
123   
124   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_height) (row_geo, row, 
125                                                              sheet);
126 }
127
128
129
130 gboolean  
131 g_sheet_row_get_visibility(const GSheetRow *row_geo,
132                                             gint row, const GtkSheet *sheet)
133 {
134   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
135
136   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility);
137   
138   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility) (row_geo, 
139                                                                   row, sheet);
140
141 }
142
143 gboolean  
144 g_sheet_row_get_sensitivity(const GSheetRow *row_geo,
145                                              gint row, const GtkSheet *sheet)
146 {
147   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
148
149   g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity);
150   
151   return (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity) (row_geo, 
152                                                                    row, sheet);
153
154 }
155
156
157 GtkSheetButton *
158 g_sheet_row_get_button(const GSheetRow *row_geo,
159                               gint row, const GtkSheet *sheet)
160 {
161   GtkSheetButton *button  = gtk_sheet_button_new();
162
163   GSheetRowIface *iface = G_SHEET_ROW_GET_IFACE (row_geo);
164
165   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
166
167   if ( iface->get_button_label)
168     button->label = iface->get_button_label(row_geo, row, sheet);
169
170   return button;
171 }
172
173
174 gint  
175 g_sheet_row_get_row_count(const GSheetRow *geo, const GtkSheet *sheet)
176 {
177   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
178
179   g_assert  ( G_SHEET_ROW_GET_IFACE (geo)->get_row_count);
180
181   return (G_SHEET_ROW_GET_IFACE (geo)->get_row_count) (geo, sheet);
182 }
183
184 /**
185  * g_sheet_row_start_pixel:
186  * @geo: the row model
187  * @row: the row number
188  * @sheet: pointer to the sheet 
189  *
190  * Returns the top y pixel for ROW.
191  * Instances may override this method in order to achieve time and/or memory
192  * optmisation.
193  *
194  * Returns: the y coordinate of the top of the row.
195  */
196
197 gint  
198 g_sheet_row_start_pixel(const GSheetRow *geo, gint row, const GtkSheet *sheet)
199 {
200   gint i;
201   gint start_pixel = 0;
202
203   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
204   g_return_val_if_fail (row >= 0, -1);
205   g_return_val_if_fail (row < 
206                         g_sheet_row_get_row_count(geo, sheet),-1);
207
208   if ( G_SHEET_ROW_GET_IFACE(geo)->top_ypixel) 
209     return (G_SHEET_ROW_GET_IFACE(geo)->top_ypixel)(geo, row, sheet);
210
211   for ( i = 0 ; i < row ; ++i ) 
212     {
213       if ( g_sheet_row_get_visibility(geo, i, sheet))
214         start_pixel += g_sheet_row_get_height(geo, i, sheet);
215     }
216   
217   return start_pixel;
218 }
219
220
221 gint  
222 g_sheet_row_pixel_to_row(const GSheetRow *geo, gint pixel, 
223                          const GtkSheet *s)
224 {
225   gint i, cy;
226   g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
227   g_return_val_if_fail (pixel >= 0, -1) ;
228
229   if ( G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row) 
230     return (G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row)(geo, pixel, s);
231
232   cy = 0;
233   for (i = 0; i < g_sheet_row_get_row_count(geo, s); ++i ) 
234     {
235       if (pixel >= cy  && 
236           pixel <= (cy + g_sheet_row_get_height(geo, i, s)) && 
237           g_sheet_row_get_visibility(geo, i, s))
238         return i;
239
240       if(g_sheet_row_get_visibility(geo, i, s))
241         cy += g_sheet_row_get_height(geo, i, s);
242     }
243
244   /* no match */
245   return g_sheet_row_get_row_count(geo, s) - 1;
246 }
247
248
249
250 void
251 g_sheet_row_rows_deleted(GSheetRow *geo, 
252                                  gint first, gint n_rows)
253 {
254   g_return_if_fail (G_IS_SHEET_ROW (geo));
255
256   g_signal_emit (geo, sheet_row_signals[ROWS_CHANGED], 0, 
257                  first, n_rows);
258 }