33 #include "gnucash-sheet.h"
34 #include "gnucash-sheetP.h"
35 #include "gnucash-color.h"
36 #include "gnucash-style.h"
37 #include "gnucash-grid.h"
38 #include "gnucash-cursor.h"
39 #include "gnucash-item-edit.h"
41 #include "gnucash-header.h"
43 static GnomeCanvasItem *parent_class;
54 gnc_header_update (GnomeCanvasItem *item,
double *affine,
55 ArtSVP *clip_path,
int flags)
57 if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update)
58 (*GNOME_CANVAS_ITEM_CLASS (parent_class)->update)
59 (item, affine, clip_path, flags);
63 item->x2 = (INT_MAX / 2) - 1;
64 item->y2 = (INT_MAX / 2) - 1;
69 gnc_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
70 int x,
int y,
int width,
int height)
78 GdkColor *bg_color, *fg_color;
82 guint32 argb, color_type;
87 virt_loc.vcell_loc.virt_row = 0;
88 virt_loc.vcell_loc.virt_col = 0;
89 virt_loc.phys_row_offset = 0;
90 virt_loc.phys_col_offset = 0;
92 if (header->sheet->use_theme_colors)
94 color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc,
96 bg_color = get_gtkrc_color(header->sheet, color_type);
97 color_type = gnc_table_get_gtkrc_fg_color (table, virt_loc);
98 fg_color = get_gtkrc_color(header->sheet, color_type);
102 argb = gnc_table_get_bg_color (table, virt_loc, NULL);
103 bg_color = gnucash_color_argb_to_gdk (argb);
104 argb = gnc_table_get_fg_color (table, virt_loc);
105 fg_color = gnucash_color_argb_to_gdk (argb);
108 h = style->dimensions->height;
109 h *= header->num_phys_rows;
110 h /= header->style->nrows;
112 gdk_gc_set_foreground (header->gc, bg_color);
114 gdk_draw_rectangle (drawable, header->gc, TRUE, 0, 0,
115 style->dimensions->width, h);
117 gdk_gc_set_line_attributes (header->gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
118 gdk_gc_set_foreground (header->gc, fg_color);
120 gdk_draw_rectangle (drawable, header->gc, FALSE, -x, -y,
121 style->dimensions->width, h);
123 gdk_draw_line (drawable, header->gc, 0, h + 1,
124 style->dimensions->width, h + 1);
126 gdk_gc_set_line_attributes (header->gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
127 gdk_gc_set_background (header->gc, &gn_white);
128 gdk_gc_set_foreground (header->gc, fg_color);
131 vcell = gnc_table_get_virtual_cell
132 (table, table->current_cursor_loc.vcell_loc);
133 cb = vcell ? vcell->cellblock : NULL;
138 for (i = 0; i < style->nrows; i++)
141 virt_loc.phys_row_offset = i;
148 for (j = 0; j < style->ncols; j++)
154 virt_loc.phys_col_offset = j;
156 cd = gnucash_style_get_cell_dimensions (style, i, j);
158 if (header->in_resize && (j == header->resize_col))
159 w = header->resize_col_width;
163 cell = gnc_cellblock_get_cell (cb, i, j);
164 if (!cell || !cell->cell_name)
170 h = cd->pixel_height;
172 gdk_draw_rectangle (drawable, header->gc, FALSE,
173 xpaint, ypaint, w, h);
176 table->current_cursor_loc.vcell_loc;
177 text = gnc_table_get_label (table, virt_loc);
181 layout = gtk_widget_create_pango_layout (GTK_WIDGET (header->sheet), text);
188 switch (gnc_table_get_align (table, virt_loc))
191 case CELL_ALIGN_LEFT:
192 pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
195 case CELL_ALIGN_RIGHT:
196 pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
199 case CELL_ALIGN_CENTER:
200 pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
204 rect.x = xpaint + CELL_HPADDING;
206 rect.width = MAX (0, w - (2 * CELL_HPADDING));
209 gdk_gc_set_clip_rectangle (header->gc, &rect);
211 gdk_draw_layout (drawable,
213 xpaint + CELL_HPADDING,
217 g_object_unref (layout);
219 gdk_gc_set_clip_rectangle (header->gc, NULL);
230 gnc_header_request_redraw (
GncHeader *header)
232 GnomeCanvas *canvas = GNOME_CANVAS_ITEM(header)->canvas;
234 if (header->style == NULL)
237 gnome_canvas_request_redraw (canvas, 0, 0,
244 gnc_header_realize (GnomeCanvasItem *item)
249 if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize)
250 GNOME_CANVAS_ITEM_CLASS (parent_class)->realize (item);
252 window = GTK_WIDGET (item->canvas)->window;
254 header->gc = gdk_gc_new (window);
259 gnc_header_unrealize (GnomeCanvasItem *item)
263 if (header->gc != NULL)
265 g_object_unref (header->gc);
269 if (header->resize_cursor != NULL)
270 gdk_cursor_unref (header->resize_cursor);
271 header->resize_cursor = NULL;
273 if (header->normal_cursor != NULL)
274 gdk_cursor_unref (header->normal_cursor);
275 header->normal_cursor = NULL;
277 if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize)
278 GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize (item);
283 gnc_header_finalize (GObject *
object)
287 header = GNC_HEADER (
object);
289 g_free (header->cursor_name);
290 header->cursor_name = NULL;
292 G_OBJECT_CLASS (parent_class)->finalize (
object);
297 gnc_header_reconfigure (
GncHeader *header)
304 g_return_if_fail (header != NULL);
305 g_return_if_fail (GNC_IS_HEADER (header));
307 canvas = GNOME_CANVAS_ITEM(header)->canvas;
308 sheet = GNUCASH_SHEET(header->sheet);
309 old_style = header->style;
311 header->style = gnucash_sheet_get_style_from_cursor
312 (sheet, header->cursor_name);
314 if (header->style == NULL)
317 sheet->width = header->style->dimensions->width;
319 w = header->style->dimensions->width;
320 h = header->style->dimensions->height;
321 h *= header->num_phys_rows;
322 h /= header->style->nrows;
325 if (header->height != h ||
326 header->width != w ||
327 header->style != old_style)
332 gnome_canvas_set_scroll_region (GNOME_CANVAS(canvas),
335 gtk_widget_set_size_request (GTK_WIDGET(canvas), -1, h);
337 gnc_header_request_redraw (header);
342 gnc_header_set_header_rows (
GncHeader *header,
345 g_return_if_fail (header != NULL);
346 g_return_if_fail (GNC_IS_HEADER (header));
348 header->num_phys_rows = num_phys_rows;
352 gnc_header_point (GnomeCanvasItem *item,
353 double x,
double y,
int cx,
int cy,
354 GnomeCanvasItem **actual_item)
366 pointer_on_resize_line (
GncHeader *header,
int x,
int y,
int *col)
369 gboolean on_the_line = FALSE;
374 for (j = 0; j < style->ncols; j++)
376 cd = gnucash_style_get_cell_dimensions (style, 0, j);
377 pixels += cd->pixel_width;
378 if (x >= pixels - 1 && x <= pixels + 1)
391 find_resize_col (
GncHeader *header,
int col)
397 if (col < 0 || col >= style->ncols)
401 while ((col + 1 < style->ncols) &&
402 (cd = gnucash_style_get_cell_dimensions (style, 0, col + 1)) &&
403 (cd->pixel_width == 0))
409 if (gnucash_style_col_is_resizable (style, col))
420 gnc_header_resize_column (
GncHeader *header, gint col, gint width)
424 gnucash_sheet_set_col_width (sheet, col, width);
426 gnucash_cursor_configure (GNUCASH_CURSOR(sheet->cursor));
427 gnc_item_edit_configure (gnucash_sheet_get_item_edit (sheet));
429 gnc_header_reconfigure (header);
430 gnucash_sheet_set_scroll_region (sheet);
431 gnucash_sheet_update_adjustments (sheet);
433 gnc_header_request_redraw (header);
434 gnucash_sheet_redraw_all (sheet);
438 gnc_header_auto_resize_column (
GncHeader *header, gint col)
442 width = gnucash_sheet_col_max_width (header->sheet, 0, col);
444 gnc_header_resize_column (header, col, width);
448 gnc_header_event (GnomeCanvasItem *item, GdkEvent *event)
451 GnomeCanvas *canvas = item->canvas;
457 case GDK_MOTION_NOTIFY:
459 gnome_canvas_w2c (canvas, event->motion.x, event->motion.y,
462 if (header->in_resize)
464 int change = x - header->resize_x;
467 if (!header->needs_ungrab)
469 gnome_canvas_item_grab (item,
470 GDK_POINTER_MOTION_MASK |
471 GDK_BUTTON_RELEASE_MASK,
472 header->resize_cursor,
474 header->needs_ungrab = TRUE;
477 new_width = header->resize_col_width + change;
481 header->resize_x = x;
482 header->resize_col_width = new_width;
483 gnc_header_request_redraw (header);
489 if (pointer_on_resize_line(header, x, y, &col) &&
490 gnucash_style_col_is_resizable (header->style, col))
491 gdk_window_set_cursor (GTK_WIDGET(canvas)->window,
492 header->resize_cursor);
494 gdk_window_set_cursor (GTK_WIDGET(canvas)->window,
495 header->normal_cursor);
498 case GDK_BUTTON_PRESS:
502 if (event->button.button != 1)
505 gnome_canvas_w2c (canvas, event->button.x, event->button.y,
508 if (pointer_on_resize_line (header, x, y, &col))
509 col = find_resize_col (header, col);
517 cd = gnucash_style_get_cell_dimensions
518 (header->style, 0, col);
520 header->in_resize = TRUE;
521 header->resize_col = col;
522 header->resize_col_width = cd->pixel_width;
523 header->resize_x = x;
528 case GDK_BUTTON_RELEASE:
530 if (event->button.button != 1)
533 gnome_canvas_w2c (canvas, event->button.x, event->button.y,
536 if (header->in_resize)
538 if (header->needs_ungrab)
540 gnome_canvas_item_ungrab (item,
542 header->needs_ungrab = FALSE;
544 gnc_header_resize_column
547 header->resize_col_width);
549 header->in_resize = FALSE;
550 header->resize_col = -1;
556 case GDK_2BUTTON_PRESS:
562 if (event->button.button != 1)
565 gnome_canvas_w2c (canvas, event->button.x, event->button.y,
568 on_line = pointer_on_resize_line (header, x, y, &ptr_col);
573 resize_col = find_resize_col (header, ptr_col);
575 resize_col = ptr_col;
579 header->in_resize = FALSE;
580 header->resize_col = -1;
581 if (header->needs_ungrab)
583 gnome_canvas_item_ungrab (item,
585 header->needs_ungrab = FALSE;
588 gnc_header_auto_resize_column (header, resize_col);
609 gnc_header_get_property (GObject *
object,
619 g_value_take_object (value, header->sheet);
621 case PROP_CURSOR_NAME:
622 g_value_set_string (value, header->cursor_name);
625 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
631 gnc_header_set_property (GObject *
object,
637 GtkLayout *layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (header)->canvas);
638 gboolean needs_update = FALSE;
644 header->sheet = GNUCASH_SHEET (g_value_get_object (value));
645 gtk_layout_set_hadjustment (layout, header->sheet->hadj);
648 case PROP_CURSOR_NAME:
649 old_name = header->cursor_name;
651 header->cursor_name = g_value_dup_string (value);
652 needs_update = !old_name || !header->cursor_name ||
653 strcmp (old_name, header->cursor_name) != 0;
657 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
661 if ((header->sheet != NULL) && needs_update)
662 gnc_header_reconfigure (header);
669 header->sheet = NULL;
670 header->cursor_name = NULL;
671 header->in_resize = FALSE;
672 header->resize_col = -1;
673 header->resize_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
674 header->normal_cursor = NULL;
677 header->style = NULL;
684 GObjectClass *object_class = G_OBJECT_CLASS (header_class);
685 GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (header_class);
687 parent_class = g_type_class_peek_parent (header_class);
689 object_class->finalize = gnc_header_finalize;
690 object_class->get_property = gnc_header_get_property;
691 object_class->set_property = gnc_header_set_property;
693 g_object_class_install_property (object_class,
695 g_param_spec_object (
"sheet",
700 g_object_class_install_property (object_class,
702 g_param_spec_string (
"cursor_name",
709 item_class->realize = gnc_header_realize;
710 item_class->unrealize = gnc_header_unrealize;
711 item_class->update = gnc_header_update;
712 item_class->draw = gnc_header_draw;
713 item_class->event = gnc_header_event;
714 item_class->point = gnc_header_point;
719 gnc_header_get_type (
void)
721 static GType gnc_header_type = 0;
723 if (!gnc_header_type)
725 static const GTypeInfo gnc_header_info =
730 (GClassInitFunc) gnc_header_class_init,
735 (GInstanceInitFunc) gnc_header_init
738 gnc_header_type = g_type_register_static (gnome_canvas_item_get_type (),
740 &gnc_header_info, 0);
743 return gnc_header_type;
748 gnc_header_realized (GtkWidget *widget, gpointer data)
750 gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window,
758 GnomeCanvasGroup *group;
759 GnomeCanvasItem *item;
762 canvas = gnome_canvas_new ();
764 g_signal_connect (G_OBJECT (canvas),
"realize",
765 G_CALLBACK (gnc_header_realized),
768 group = GNOME_CANVAS_GROUP (GNOME_CANVAS (canvas)->root);
770 item = gnome_canvas_item_new (group,
771 gnc_header_get_type (),
773 "cursor_name", CURSOR_HEADER,
776 sheet->header_item = item;
778 gtk_widget_show (canvas);