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