Branch data Line data Source code
1 : : /********************************************************************\
2 : : * This program is free software; you can redistribute it and/or *
3 : : * modify it under the terms of the GNU General Public License as *
4 : : * published by the Free Software Foundation; either version 2 of *
5 : : * the License, or (at your option) any later version. *
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 *
10 : : * GNU General Public License for more details. *
11 : : * *
12 : : * You should have received a copy of the GNU General Public License*
13 : : * along with this program; if not, contact: *
14 : : * *
15 : : * Free Software Foundation Voice: +1-617-542-5942 *
16 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
17 : : * Boston, MA 02110-1301, USA gnu@gnu.org *
18 : : * *
19 : : \********************************************************************/
20 : :
21 : : /*
22 : : * The Gnucash Header Canvas
23 : : *
24 : : * Authors:
25 : : * Heath Martin <martinh@pegasus.cc.ucf.edu>
26 : : * Dave Peticolas <dave@krondo.com>
27 : : */
28 : :
29 : : #include <config.h>
30 : :
31 : : #include <string.h>
32 : :
33 : : #include "gnucash-sheet.h"
34 : : #include "gnucash-sheetP.h"
35 : : #include "gnucash-color.h"
36 : : #include "gnucash-style.h"
37 : : #include "gnucash-cursor.h"
38 : : #include "gnucash-item-edit.h"
39 : : #include "gnc-gtk-utils.h"
40 : :
41 : : #include "gnucash-header.h"
42 : :
43 : : enum
44 : : {
45 : : PROP_0,
46 : : PROP_SHEET, /* the sheet this header is associated with */
47 : : PROP_CURSOR_NAME, /* the name of the current cursor */
48 : : };
49 : :
50 : 0 : G_DEFINE_TYPE (GncHeader, gnc_header, GTK_TYPE_LAYOUT)
51 : :
52 : : static void
53 : 0 : gnc_header_draw_offscreen (GncHeader *header)
54 : : {
55 : 0 : SheetBlockStyle *style = header->style;
56 : 0 : GncItemEdit *item_edit = GNC_ITEM_EDIT(header->sheet->item_editor);
57 : 0 : Table *table = header->sheet->table;
58 : : VirtualLocation virt_loc;
59 : : VirtualCell *vcell;
60 : : guint32 color_type;
61 : 0 : GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(header));
62 : : GdkRGBA color;
63 : : int row_offset;
64 : : CellBlock *cb;
65 : : int i;
66 : : cairo_t *cr;
67 : :
68 : 0 : virt_loc.vcell_loc.virt_row = 0;
69 : 0 : virt_loc.vcell_loc.virt_col = 0;
70 : 0 : virt_loc.phys_row_offset = 0;
71 : 0 : virt_loc.phys_col_offset = 0;
72 : :
73 : 0 : gtk_style_context_save (stylectxt);
74 : :
75 : : // Get the color type and apply the css class
76 : 0 : color_type = gnc_table_get_color (table, virt_loc, NULL);
77 : 0 : gnucash_get_style_classes (header->sheet, stylectxt, color_type, FALSE);
78 : :
79 : 0 : if (header->surface)
80 : 0 : cairo_surface_destroy (header->surface);
81 : 0 : header->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
82 : : header->width,
83 : : header->height);
84 : :
85 : 0 : cr = cairo_create (header->surface);
86 : :
87 : : // Fill background color of header
88 : 0 : gtk_render_background (stylectxt, cr, 0, 0, header->width, header->height);
89 : :
90 : 0 : gdk_rgba_parse (&color, "black");
91 : 0 : cairo_set_source_rgb (cr, color.red, color.green, color.blue);
92 : 0 : cairo_rectangle (cr, 0.5, 0.5, header->width - 1.0, header->height - 1.0);
93 : 0 : cairo_set_line_width (cr, 1.0);
94 : 0 : cairo_stroke (cr);
95 : :
96 : : // Draw bottom horizontal line, makes bottom line thicker
97 : 0 : cairo_move_to (cr, 0.5, header->height - 1.5);
98 : 0 : cairo_line_to (cr, header->width - 1.0, header->height - 1.5);
99 : 0 : cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
100 : 0 : cairo_set_line_width (cr, 1.0);
101 : 0 : cairo_stroke (cr);
102 : :
103 : : /*font = gnucash_register_font;*/
104 : :
105 : 0 : vcell = gnc_table_get_virtual_cell
106 : : (table, table->current_cursor_loc.vcell_loc);
107 : 0 : cb = vcell ? vcell->cellblock : NULL;
108 : 0 : row_offset = 0;
109 : :
110 : 0 : for (i = 0; i < style->nrows; i++)
111 : : {
112 : 0 : int col_offset = 0;
113 : 0 : int height = 0, j;
114 : 0 : virt_loc.phys_row_offset = i;
115 : :
116 : : /* TODO: This routine is duplicated in several places.
117 : : Can we abstract at least the cell drawing routine?
118 : : That way we'll be sure everything is drawn
119 : : consistently, and cut down on maintenance issues. */
120 : :
121 : 0 : for (j = 0; j < style->ncols; j++)
122 : : {
123 : : CellDimensions *cd;
124 : : BasicCell *cell;
125 : : const char *text;
126 : : int width;
127 : : PangoLayout *layout;
128 : : PangoRectangle logical_rect;
129 : : GdkRectangle rect;
130 : : int x_offset;
131 : :
132 : 0 : virt_loc.phys_col_offset = j;
133 : :
134 : 0 : cd = gnucash_style_get_cell_dimensions (style, i, j);
135 : 0 : if (!cd) continue;
136 : :
137 : 0 : height = cd->pixel_height;
138 : 0 : if (header->in_resize && (j == header->resize_col))
139 : 0 : width = header->resize_col_width;
140 : : else
141 : 0 : width = cd->pixel_width;
142 : :
143 : 0 : cell = gnc_cellblock_get_cell (cb, i, j);
144 : 0 : if (!cell || !cell->cell_name)
145 : : {
146 : 0 : col_offset += width;
147 : 0 : continue;
148 : : }
149 : :
150 : 0 : cairo_rectangle (cr, col_offset - 0.5, row_offset + 0.5, width, height);
151 : 0 : cairo_set_line_width (cr, 1.0);
152 : 0 : cairo_stroke (cr);
153 : :
154 : 0 : virt_loc.vcell_loc =
155 : : table->current_cursor_loc.vcell_loc;
156 : 0 : text = gnc_table_get_label (table, virt_loc);
157 : 0 : if (!text)
158 : 0 : text = "";
159 : :
160 : 0 : layout = gtk_widget_create_pango_layout (GTK_WIDGET(header->sheet), text);
161 : :
162 : 0 : pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
163 : :
164 : 0 : gnucash_sheet_set_text_bounds (header->sheet, &rect,
165 : : col_offset, row_offset, width, height);
166 : :
167 : 0 : cairo_save (cr);
168 : 0 : cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
169 : 0 : cairo_clip (cr);
170 : :
171 : 0 : x_offset = gnucash_sheet_get_text_offset (header->sheet, virt_loc,
172 : : rect.width, logical_rect.width);
173 : :
174 : 0 : gtk_render_layout (stylectxt, cr, rect.x + x_offset,
175 : 0 : rect.y + gnc_item_edit_get_padding_border (item_edit, top), layout);
176 : :
177 : 0 : cairo_restore (cr);
178 : 0 : g_object_unref (layout);
179 : :
180 : 0 : col_offset += width;
181 : : }
182 : 0 : row_offset += height;
183 : : }
184 : 0 : gtk_style_context_restore (stylectxt);
185 : :
186 : 0 : cairo_destroy (cr);
187 : 0 : }
188 : :
189 : :
190 : : gint
191 : 0 : gnc_header_get_cell_offset (GncHeader *header, gint col, gint *cell_width)
192 : : {
193 : 0 : SheetBlockStyle *style = header->style;
194 : : gint j;
195 : 0 : gint offset = 0;
196 : :
197 : 0 : for (j = 0; j < style->ncols; j++)
198 : : {
199 : : CellDimensions *cd;
200 : :
201 : 0 : cd = gnucash_style_get_cell_dimensions (style, 0, j);
202 : 0 : if (!cd) continue;
203 : :
204 : 0 : if (j == col)
205 : : {
206 : 0 : *cell_width = cd->pixel_width;
207 : 0 : break;
208 : : }
209 : 0 : offset = offset + cd->pixel_width;
210 : : }
211 : 0 : return offset;
212 : : }
213 : :
214 : :
215 : : static gboolean
216 : 0 : gnc_header_draw (GtkWidget *header, cairo_t *cr)
217 : : {
218 : 0 : GnucashSheet *sheet = GNC_HEADER(header)->sheet;
219 : 0 : GdkWindow *sheet_layout_win = gtk_layout_get_bin_window (GTK_LAYOUT(sheet));
220 : : gint x, y;
221 : :
222 : : // use this to get the scroll x value to align the header
223 : 0 : gdk_window_get_position (sheet_layout_win, &x, &y);
224 : :
225 : : // if the register page is moved to another window, the surface is
226 : : // not created so test for a surface and create one if null
227 : 0 : if (GNC_HEADER(header)->surface == NULL)
228 : 0 : gnc_header_draw_offscreen (GNC_HEADER(header));
229 : :
230 : 0 : cairo_set_source_surface (cr, GNC_HEADER(header)->surface, x, 0);
231 : 0 : cairo_paint (cr);
232 : :
233 : 0 : return TRUE;
234 : : }
235 : :
236 : :
237 : : void
238 : 0 : gnc_header_request_redraw (GncHeader *header)
239 : : {
240 : 0 : if (!header->style)
241 : 0 : return;
242 : :
243 : 0 : gnc_header_draw_offscreen (header);
244 : 0 : gtk_widget_queue_draw (GTK_WIDGET(header));
245 : : }
246 : :
247 : :
248 : : static void
249 : 0 : gnc_header_unrealize (GtkWidget *widget)
250 : : {
251 : 0 : GncHeader *header = GNC_HEADER(widget);
252 : 0 : if (header->surface)
253 : 0 : cairo_surface_destroy (header->surface);
254 : 0 : header->surface = NULL;
255 : :
256 : 0 : if (header->resize_cursor)
257 : 0 : g_object_unref (header->resize_cursor);
258 : 0 : header->resize_cursor = NULL;
259 : :
260 : 0 : if (header->normal_cursor)
261 : 0 : g_object_unref (header->normal_cursor);
262 : 0 : header->normal_cursor = NULL;
263 : :
264 : 0 : if (GTK_WIDGET_CLASS(gnc_header_parent_class)->unrealize)
265 : 0 : GTK_WIDGET_CLASS(gnc_header_parent_class)->unrealize (GTK_WIDGET(header));
266 : 0 : }
267 : :
268 : :
269 : : static void
270 : 0 : gnc_header_finalize (GObject *object)
271 : : {
272 : : GncHeader *header;
273 : :
274 : 0 : header = GNC_HEADER(object);
275 : :
276 : 0 : g_free (header->cursor_name);
277 : 0 : header->cursor_name = NULL;
278 : :
279 : 0 : G_OBJECT_CLASS(gnc_header_parent_class)->finalize (object);
280 : 0 : }
281 : :
282 : :
283 : : void
284 : 0 : gnc_header_reconfigure (GncHeader *header)
285 : : {
286 : : GnucashSheet *sheet;
287 : : SheetBlockStyle *old_style;
288 : : int w, h;
289 : :
290 : 0 : g_return_if_fail (header != NULL);
291 : 0 : g_return_if_fail (GNC_IS_HEADER(header));
292 : :
293 : 0 : sheet = GNUCASH_SHEET(header->sheet);
294 : 0 : old_style = header->style;
295 : :
296 : 0 : header->style = gnucash_sheet_get_style_from_cursor
297 : 0 : (sheet, header->cursor_name);
298 : :
299 : 0 : if (header->style == NULL)
300 : 0 : return;
301 : :
302 : 0 : sheet->width = header->style->dimensions->width;
303 : :
304 : 0 : w = header->style->dimensions->width;
305 : 0 : h = header->style->dimensions->height;
306 : 0 : h *= header->num_phys_rows;
307 : 0 : h /= header->style->nrows;
308 : 0 : h += 2;
309 : :
310 : 0 : if (header->height != h ||
311 : 0 : header->width != w ||
312 : 0 : header->style != old_style)
313 : : {
314 : 0 : header->height = h;
315 : 0 : header->width = w;
316 : 0 : gtk_layout_set_size (GTK_LAYOUT(header), w, h);
317 : 0 : gtk_widget_set_size_request (GTK_WIDGET(header), -1, h);
318 : 0 : gnc_header_request_redraw (header);
319 : : }
320 : : }
321 : :
322 : : void
323 : 0 : gnc_header_set_header_rows (GncHeader *header,
324 : : int num_phys_rows)
325 : : {
326 : 0 : g_return_if_fail (header != NULL);
327 : 0 : g_return_if_fail (GNC_IS_HEADER(header));
328 : :
329 : 0 : header->num_phys_rows = num_phys_rows;
330 : : }
331 : :
332 : : /*
333 : : * Returns FALSE if pointer not on a resize line, else returns
334 : : * TRUE. Returns the index of the column to the left in the col
335 : : * argument.
336 : : */
337 : : static gboolean
338 : 0 : pointer_on_resize_line (GncHeader *header, int x, G_GNUC_UNUSED int y, int *col)
339 : : {
340 : 0 : SheetBlockStyle *style = header->style;
341 : 0 : gboolean on_the_line = FALSE;
342 : : CellDimensions *cd;
343 : 0 : int pixels = 0;
344 : : int j;
345 : :
346 : 0 : for (j = 0; j < style->ncols; j++)
347 : : {
348 : 0 : cd = gnucash_style_get_cell_dimensions (style, 0, j);
349 : 0 : if (!cd) continue;
350 : :
351 : 0 : pixels += cd->pixel_width;
352 : 0 : if (x >= pixels - 1 && x <= pixels + 1)
353 : 0 : on_the_line = TRUE;
354 : 0 : if (x <= pixels + 1)
355 : 0 : break;
356 : : }
357 : :
358 : 0 : if (col != NULL)
359 : 0 : *col = j;
360 : :
361 : 0 : return on_the_line;
362 : : }
363 : :
364 : : static int
365 : 0 : find_resize_col (GncHeader *header, int col)
366 : : {
367 : 0 : SheetBlockStyle *style = header->style;
368 : : CellDimensions *cd;
369 : 0 : int start = col;
370 : :
371 : 0 : if (col < 0 || col >= style->ncols)
372 : 0 : return -1;
373 : :
374 : : /* skip to the right over zero-width columns */
375 : 0 : while ((col + 1 < style->ncols) &&
376 : 0 : (cd = gnucash_style_get_cell_dimensions (style, 0, col + 1)) &&
377 : 0 : cd && (cd->pixel_width == 0))
378 : 0 : ++col;
379 : :
380 : : /* now go back left till we have a resizable column */
381 : 0 : while (col >= start)
382 : : {
383 : 0 : if (gnucash_style_col_is_resizable (style, col))
384 : 0 : return col;
385 : : else
386 : 0 : col--;
387 : : }
388 : :
389 : : /* didn't find a resizable column to the right of col */
390 : 0 : return -1;
391 : : }
392 : :
393 : : static void
394 : 0 : gnc_header_resize_column (GncHeader *header, gint col, gint width)
395 : : {
396 : 0 : GnucashSheet *sheet = header->sheet;
397 : :
398 : 0 : gnucash_sheet_set_col_width (sheet, col, width);
399 : :
400 : 0 : gnucash_cursor_configure (GNUCASH_CURSOR(sheet->cursor));
401 : 0 : gnc_item_edit_configure (gnucash_sheet_get_item_edit (sheet));
402 : :
403 : 0 : gnc_header_reconfigure (header);
404 : :
405 : 0 : gnucash_sheet_set_scroll_region (sheet);
406 : 0 : gnucash_sheet_update_adjustments (sheet);
407 : :
408 : 0 : gnc_header_request_redraw (header);
409 : 0 : gnucash_sheet_redraw_all (sheet);
410 : 0 : }
411 : :
412 : : static void
413 : 0 : gnc_header_auto_resize_column (GncHeader *header, gint col)
414 : : {
415 : : int width;
416 : :
417 : 0 : width = gnucash_sheet_col_max_width (header->sheet, 0, col);
418 : :
419 : 0 : gnc_header_resize_column (header, col, width);
420 : 0 : }
421 : :
422 : : static gint
423 : 0 : gnc_header_event (GtkWidget *widget, GdkEvent *event)
424 : : {
425 : 0 : GncHeader *header = GNC_HEADER(widget);
426 : 0 : GdkWindow *window = gtk_widget_get_window (widget);
427 : : int x, y;
428 : : int col;
429 : :
430 : 0 : if (!header->resize_cursor)
431 : 0 : header->resize_cursor = gdk_cursor_new_for_display (gdk_window_get_display (window),
432 : : GDK_SB_H_DOUBLE_ARROW);
433 : :
434 : 0 : switch (event->type)
435 : : {
436 : 0 : case GDK_MOTION_NOTIFY:
437 : 0 : x = event->motion.x;
438 : 0 : y = event->motion.y;
439 : :
440 : 0 : if (header->in_resize)
441 : : {
442 : 0 : int change = x - header->resize_x;
443 : 0 : int new_width = header->resize_col_width + change;
444 : :
445 : 0 : if (new_width >= 0)
446 : : {
447 : 0 : header->resize_x = x;
448 : 0 : header->resize_col_width = new_width;
449 : 0 : gnc_header_request_redraw (header);
450 : : }
451 : :
452 : 0 : break;
453 : : }
454 : :
455 : 0 : if (pointer_on_resize_line (header, x, y, &col) &&
456 : 0 : gnucash_style_col_is_resizable (header->style, col))
457 : 0 : gdk_window_set_cursor (window, header->resize_cursor);
458 : : else
459 : 0 : gdk_window_set_cursor (window, header->normal_cursor);
460 : 0 : break;
461 : :
462 : 0 : case GDK_BUTTON_PRESS:
463 : : {
464 : : int col;
465 : :
466 : 0 : if (event->button.button != 1)
467 : 0 : break;
468 : :
469 : 0 : x = event->button.x;
470 : 0 : y = event->button.y;
471 : :
472 : 0 : if (pointer_on_resize_line (header, x, y, &col))
473 : 0 : col = find_resize_col (header, col);
474 : : else
475 : 0 : col = -1;
476 : :
477 : 0 : if (col > -1)
478 : : {
479 : : CellDimensions *cd;
480 : :
481 : 0 : cd = gnucash_style_get_cell_dimensions
482 : : (header->style, 0, col);
483 : 0 : if (!cd) break;
484 : :
485 : 0 : header->in_resize = TRUE;
486 : 0 : header->resize_col = col;
487 : 0 : header->resize_col_width = cd->pixel_width;
488 : 0 : header->resize_x = x;
489 : : }
490 : 0 : break;
491 : : }
492 : 0 : case GDK_BUTTON_RELEASE:
493 : : {
494 : 0 : if (event->button.button != 1)
495 : 0 : break;
496 : :
497 : 0 : if (header->in_resize)
498 : : {
499 : 0 : if (header->resize_col_width == 0)
500 : 0 : header->resize_col_width = 1;
501 : :
502 : 0 : gnc_header_resize_column
503 : : (header,
504 : : header->resize_col,
505 : : header->resize_col_width);
506 : 0 : header->in_resize = FALSE;
507 : 0 : header->resize_col = -1;
508 : 0 : gnc_header_request_redraw (header);
509 : : }
510 : 0 : break;
511 : : }
512 : :
513 : 0 : case GDK_2BUTTON_PRESS:
514 : : {
515 : : gboolean on_line;
516 : : int ptr_col;
517 : : int resize_col;
518 : :
519 : 0 : if (event->button.button != 1)
520 : 0 : break;
521 : :
522 : 0 : x = event->button.x;
523 : 0 : y = event->button.y;
524 : :
525 : 0 : on_line = pointer_on_resize_line (header, x, y, &ptr_col);
526 : :
527 : : /* If we're on a resize line and the column to the right is zero
528 : : width, resize that one. */
529 : 0 : if (on_line)
530 : 0 : resize_col = find_resize_col (header, ptr_col);
531 : : else
532 : 0 : resize_col = ptr_col;
533 : :
534 : 0 : if (resize_col > -1)
535 : : {
536 : 0 : header->in_resize = FALSE;
537 : 0 : header->resize_col = -1;
538 : 0 : gnc_header_auto_resize_column (header, resize_col);
539 : : }
540 : : }
541 : 0 : break;
542 : :
543 : 0 : default:
544 : 0 : break;
545 : : }
546 : 0 : return FALSE;
547 : : }
548 : :
549 : :
550 : : /* Note that g_value_set_object() refs the object, as does
551 : : * g_object_get(). But g_object_get() only unrefs once when it disgorges
552 : : * the object, leaving an unbalanced ref, which leaks. So instead of
553 : : * using g_value_set_object(), use g_value_take_object() which doesn't
554 : : * ref the object when used in get_property().
555 : : */
556 : : static void
557 : 0 : gnc_header_get_property (GObject *object,
558 : : guint param_id,
559 : : GValue *value,
560 : : GParamSpec *pspec)
561 : : {
562 : 0 : GncHeader *header = GNC_HEADER(object);
563 : :
564 : 0 : switch (param_id)
565 : : {
566 : 0 : case PROP_SHEET:
567 : 0 : g_value_take_object (value, header->sheet);
568 : 0 : break;
569 : 0 : case PROP_CURSOR_NAME:
570 : 0 : g_value_set_string (value, header->cursor_name);
571 : 0 : break;
572 : 0 : default:
573 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
574 : 0 : break;
575 : : }
576 : 0 : }
577 : :
578 : : static void
579 : 0 : gnc_header_set_property (GObject *object,
580 : : guint param_id,
581 : : const GValue *value,
582 : : GParamSpec *pspec)
583 : : {
584 : 0 : GncHeader *header = GNC_HEADER(object);
585 : 0 : GtkLayout *layout = GTK_LAYOUT(header);
586 : 0 : gboolean needs_update = FALSE;
587 : : gchar *old_name;
588 : :
589 : 0 : switch (param_id)
590 : : {
591 : 0 : case PROP_SHEET:
592 : 0 : header->sheet = GNUCASH_SHEET(g_value_get_object (value));
593 : 0 : gtk_scrollable_set_hadjustment (GTK_SCROLLABLE(layout), header->sheet->hadj);
594 : 0 : needs_update = TRUE;
595 : 0 : break;
596 : 0 : case PROP_CURSOR_NAME:
597 : 0 : old_name = header->cursor_name;
598 : :
599 : 0 : header->cursor_name = g_value_dup_string (value);
600 : 0 : needs_update = !old_name || !header->cursor_name ||
601 : 0 : strcmp (old_name, header->cursor_name) != 0;
602 : 0 : g_free (old_name);
603 : 0 : break;
604 : 0 : default:
605 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
606 : 0 : break;
607 : : }
608 : :
609 : 0 : if ((header->sheet != NULL) && needs_update)
610 : 0 : gnc_header_reconfigure (header);
611 : 0 : }
612 : :
613 : :
614 : : static void
615 : 0 : gnc_header_init (GncHeader *header)
616 : : {
617 : 0 : header->sheet = NULL;
618 : 0 : header->cursor_name = NULL;
619 : 0 : header->in_resize = FALSE;
620 : 0 : header->resize_col = -1;
621 : 0 : header->resize_cursor = NULL;
622 : 0 : header->normal_cursor = NULL;
623 : 0 : header->height = 20;
624 : 0 : header->width = 400;
625 : 0 : header->style = NULL;
626 : :
627 : 0 : gtk_widget_add_events (GTK_WIDGET(header),
628 : : (GDK_EXPOSURE_MASK
629 : : | GDK_BUTTON_PRESS_MASK
630 : : | GDK_BUTTON_RELEASE_MASK
631 : : | GDK_POINTER_MOTION_MASK
632 : : | GDK_POINTER_MOTION_HINT_MASK));
633 : :
634 : 0 : g_signal_connect (G_OBJECT(header), "configure_event",
635 : : G_CALLBACK(gnc_header_reconfigure), NULL);
636 : 0 : gtk_widget_show_all (GTK_WIDGET(header));
637 : 0 : }
638 : :
639 : :
640 : : static void
641 : 0 : gnc_header_class_init (GncHeaderClass *header_class)
642 : : {
643 : 0 : GObjectClass *object_class = G_OBJECT_CLASS(header_class);
644 : 0 : GtkWidgetClass *item_class = GTK_WIDGET_CLASS(header_class);
645 : :
646 : 0 : gtk_widget_class_set_css_name (GTK_WIDGET_CLASS(header_class), "gnc-id-header");
647 : :
648 : 0 : object_class->finalize = gnc_header_finalize;
649 : 0 : object_class->get_property = gnc_header_get_property;
650 : 0 : object_class->set_property = gnc_header_set_property;
651 : :
652 : 0 : g_object_class_install_property (object_class,
653 : : PROP_SHEET,
654 : : g_param_spec_object ("sheet",
655 : : "Sheet Value",
656 : : "Sheet Value",
657 : : GNUCASH_TYPE_SHEET,
658 : : G_PARAM_READWRITE));
659 : 0 : g_object_class_install_property (object_class,
660 : : PROP_CURSOR_NAME,
661 : : g_param_spec_string ("cursor_name",
662 : : "Cursor Name",
663 : : "Cursor Name",
664 : : CURSOR_HEADER,
665 : : G_PARAM_READWRITE));
666 : :
667 : :
668 : 0 : item_class->unrealize = gnc_header_unrealize;
669 : 0 : item_class->draw = gnc_header_draw;
670 : 0 : item_class->event = gnc_header_event;
671 : 0 : }
672 : :
673 : : GtkWidget *
674 : 0 : gnc_header_new (GnucashSheet *sheet)
675 : : {
676 : : GtkWidget *layout;
677 : :
678 : 0 : layout = g_object_new (GNC_TYPE_HEADER,
679 : : "sheet", sheet,
680 : : "cursor_name", CURSOR_HEADER,
681 : : NULL);
682 : :
683 : 0 : sheet->header_item = layout;
684 : 0 : return layout;
685 : : }
686 : :
687 : :
|