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