26 #include "gnucash-color.h"
27 #include "gnucash-grid.h"
28 #include "gnucash-item-edit.h"
29 #include "gnucash-sheet.h"
30 #include "gnucash-sheetP.h"
31 #include "gnucash-style.h"
36 #define DEFAULT_STYLE_WIDTH 680
52 key = style->cursor->num_rows;
62 key = style->cursor->num_rows;
64 return g_memdup(&key,
sizeof(key));
68 cell_dimensions_construct (gpointer _cd, gpointer user_data)
73 cd->can_span_over = TRUE;
84 dimensions->nrows = style->nrows;
85 dimensions->ncols = style->ncols;
87 dimensions->cell_dimensions = g_table_new (
sizeof (
CellDimensions),
88 cell_dimensions_construct,
91 g_table_resize (dimensions->cell_dimensions,
92 style->nrows, style->ncols);
100 if (dimensions == NULL)
103 g_table_destroy (dimensions->cell_dimensions);
104 dimensions->cell_dimensions = NULL;
115 dimensions = g_hash_table_lookup (sheet->dimensions_hash_table,
116 style_get_key (style));
120 dimensions = style_dimensions_new (style);
121 g_hash_table_insert (sheet->dimensions_hash_table,
122 style_create_key (style), dimensions);
125 dimensions->refcount++;
127 style->dimensions = dimensions;
132 gnucash_style_get_cell_dimensions (
SheetBlockStyle *style,
int row,
int col)
136 if (style->dimensions == NULL)
138 if (style->dimensions->cell_dimensions == NULL)
141 return g_table_index (style->dimensions->cell_dimensions, row, col);
145 compute_row_width (
BlockDimensions *dimensions,
int row,
int col1,
int col2)
151 col2 = MIN(col2, dimensions->ncols - 1);
153 for (j = col1; j <= col2; j++)
156 cd = g_table_index (dimensions->cell_dimensions, row, j);
157 width += cd->pixel_width;
172 gint max_height = -1;
177 for (row = 0; row < cursor->num_rows; row++)
179 for (col = 0; col < cursor->num_cols; col++)
185 cd = g_table_index (dimensions->cell_dimensions,
188 cell = gnc_cellblock_get_cell (cursor, row, col);
192 text = cell->sample_text;
194 cd->can_span_over = FALSE;
198 layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text);
199 pango_layout_get_pixel_size (layout, &width, &cd->pixel_height);
200 g_object_unref (layout);
201 width += 2 * CELL_HPADDING;
202 cd->pixel_height += 2 * CELL_VPADDING;
207 cd->pixel_height = (2 * CELL_VPADDING);
210 max_height = MAX(max_height, cd->pixel_height);
212 if (cd->pixel_width > 0)
215 if (cell && cell->is_popup)
216 width += gnc_item_edit_get_toggle_offset
219 cd->pixel_width = MAX (cd->pixel_width, width);
222 cd = g_table_index (dimensions->cell_dimensions, row, 0);
223 dimensions->height += max_height;
226 for (row = 0; row < cursor->num_rows; row++)
228 for (col = 0; col < cursor->num_cols; col++)
230 cd = g_table_index (dimensions->cell_dimensions,
232 cd->pixel_height = max_height;
241 set_dimensions_pass_two (
GnucashSheet *sheet,
int default_width)
256 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
257 dimensions = style->dimensions;
258 cd_table = dimensions->cell_dimensions;
259 cursor = style->cursor;
262 num_cols = cursor->num_cols;
263 widths = g_new (
int, num_cols);
266 for (col = 0; col < num_cols; col++)
268 cd = g_table_index (cd_table, 0, col);
270 widths[col] = cd->pixel_width;
271 width += cd->pixel_width;
274 if (width < default_width)
275 for (col = 0; col < num_cols; col++)
279 cell = gnc_cellblock_get_cell (cursor, 0, col);
281 if (!cell || !cell->expandable)
284 cd = g_table_index (cd_table, 0, col);
286 cd->pixel_width += (default_width - width);
287 width += (default_width - width);
288 widths[col] = cd->pixel_width;
292 else if (width > default_width && width == sheet->window_width)
296 for (col = 0; col < num_cols; col++)
304 cell = gnc_cellblock_get_cell (cursor, 0, col);
306 if (!cell || !cell->expandable)
309 cd = g_table_index (cd_table, 0, col);
311 old_width = cd->pixel_width;
313 cd->pixel_width += (default_width - width);
315 text = cell->sample_text;
318 layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text);
319 pango_layout_get_pixel_size (layout, &sample_width, NULL);
320 g_object_unref (layout);
322 sample_width += 2 * CELL_HPADDING;
327 cd->pixel_width = MAX (cd->pixel_width, sample_width);
329 width += cd->pixel_width - old_width;
330 widths[col] = cd->pixel_width;
336 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
339 for (node = cursors; node; node = node->next)
342 style = gnucash_sheet_get_style_from_cursor
343 (sheet, cursor->cursor_name);
344 dimensions = style->dimensions;
345 cd_table = dimensions->cell_dimensions;
347 for (row = 0; row < cursor->num_rows; row++)
348 for (col = 0; col < num_cols; col++)
350 cd = g_table_index (cd_table, row, col);
352 cd->pixel_width = widths[col];
357 for (node = cursors; node; node = node->next)
362 style = gnucash_sheet_get_style_from_cursor
363 (sheet, cursor->cursor_name);
364 dimensions = style->dimensions;
365 cd_table = dimensions->cell_dimensions;
367 for (row = 0; row < cursor->num_rows; row++)
371 for (col = 0; col < num_cols; col++)
375 cell = gnc_cellblock_get_cell (cursor,
380 cd = g_table_index (cd_table, row, col);
388 if (!cd->can_span_over)
394 if (cell->sample_text != NULL)
400 if (cd->pixel_width <= 0)
403 cd_span->pixel_width += cd->pixel_width;
417 dimensions = style->dimensions;
419 return compute_row_width(dimensions, row, 0, dimensions->ncols - 1);
428 for (i = 0; i < dimensions->nrows; i++)
432 for (j = 0; j < dimensions->ncols; j++)
436 cd = g_table_index (dimensions->cell_dimensions, i, j);
439 x += cd->pixel_width;
451 for (i = 0; i < dimensions->nrows; i++)
453 for (j = 0; j < dimensions->ncols; j++)
455 cd = g_table_index (dimensions->cell_dimensions, i, j);
458 cd = g_table_index (dimensions->cell_dimensions, i, 0);
459 y += cd->pixel_height;
470 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
472 for (node = cursors; node; node = node->next)
479 style = gnucash_sheet_get_style_from_cursor
480 (sheet, cursor->cursor_name);
481 dimensions = style->dimensions;
483 dimensions->width = compute_row_width (dimensions, 0, 0,
484 dimensions->ncols - 1);
486 compute_cell_origins_x (dimensions);
487 compute_cell_origins_y (dimensions);
492 styles_recompute_layout_dimensions (
GnucashSheet *sheet,
int default_width)
500 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
502 for (node = cursors; node; node = node->next)
506 style = gnucash_sheet_get_style_from_cursor
507 (sheet, cursor->cursor_name);
509 dimensions = style->dimensions;
511 dimensions->height = 0;
512 dimensions->width = default_width;
514 set_dimensions_pass_one (sheet, cursor, dimensions);
517 set_dimensions_pass_two (sheet, default_width);
518 set_dimensions_pass_three (sheet);
522 gnucash_sheet_styles_set_dimensions (
GnucashSheet *sheet,
int default_width)
524 g_return_if_fail (sheet != NULL);
525 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
527 styles_recompute_layout_dimensions (sheet, default_width);
533 if (col < 0 || col >= style->ncols)
540 gnucash_sheet_set_col_width (
GnucashSheet *sheet,
int col,
int width)
547 g_return_if_fail (sheet != NULL);
548 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
549 g_return_if_fail (col >= 0);
554 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
556 g_return_if_fail (col < style->ncols);
558 cd = gnucash_style_get_cell_dimensions (style, 0, col);
561 diff = cd->pixel_width - width;
562 cd->pixel_width = width;
564 total = MAX (sheet->window_width, sheet->width - diff);
566 set_dimensions_pass_two (sheet, total);
567 set_dimensions_pass_three (sheet);
582 PhysicalCellBorderLineStyle line_style;
584 g_return_if_fail (sheet != NULL);
585 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
587 line_style = sheet->use_horizontal_lines ?
588 CELL_BORDER_LINE_NORMAL : CELL_BORDER_LINE_NONE;
590 borders->top = line_style;
591 borders->bottom = line_style;
593 line_style = sheet->use_vertical_lines ?
594 CELL_BORDER_LINE_NORMAL : CELL_BORDER_LINE_NONE;
596 borders->left = line_style;
597 borders->right = line_style;
599 if (virt_loc.phys_col_offset == 0)
600 borders->left = CELL_BORDER_LINE_NORMAL;
602 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
604 if (virt_loc.phys_col_offset == (style->ncols - 1))
605 borders->right = CELL_BORDER_LINE_NORMAL;
607 if (virt_cell_loc_equal (virt_loc.vcell_loc,
608 sheet->table->current_cursor_loc.vcell_loc))
610 borders->top = CELL_BORDER_LINE_NORMAL;
611 borders->bottom = CELL_BORDER_LINE_NORMAL;
614 gnc_table_get_borders (sheet->table, virt_loc, borders);
623 g_return_val_if_fail (sheet != NULL, NULL);
624 g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL);
625 g_return_val_if_fail (cursor != NULL, NULL);
629 style->cursor = cursor;
631 style->nrows = cursor->num_rows;
632 style->ncols = cursor->num_cols;
634 gnucash_style_dimensions_init (sheet, style);
640 destroy_style_helper (gpointer key, gpointer value, gpointer user_data)
642 char *cursor_name = key;
646 gnucash_sheet_style_destroy (sheet, style);
647 g_free (cursor_name);
653 g_return_if_fail (sheet != NULL);
654 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
656 g_hash_table_foreach (sheet->cursor_styles,
657 destroy_style_helper, sheet);
666 g_return_if_fail (sheet != NULL);
667 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
669 gnucash_sheet_clear_styles (sheet);
671 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
673 for (node = cursors; node; node = node->next)
677 g_hash_table_insert (sheet->cursor_styles,
678 g_strdup (cursor->cursor_name),
679 gnucash_sheet_style_new (sheet, cursor));
686 g_return_if_fail (sheet != NULL);
687 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
689 ENTER(
"sheet=%p", sheet);
691 gnucash_sheet_styles_set_dimensions (sheet, DEFAULT_STYLE_WIDTH);
704 style->dimensions->refcount--;
706 if (style->dimensions->refcount == 0)
708 g_hash_table_remove (sheet->dimensions_hash_table,
709 style_get_key (style));
710 style_dimensions_destroy (style->dimensions);
719 gint cell_row, gint cell_col,
725 g_return_if_fail (style != NULL);
726 g_return_if_fail (cell_row >= 0 && cell_row <= style->nrows);
727 g_return_if_fail (cell_col >= 0 && cell_col <= style->ncols);
729 cd = gnucash_style_get_cell_dimensions (style, cell_row, cell_col);
733 *h = cd->pixel_height;
734 *w = cd->pixel_width;
743 g_return_val_if_fail (sheet != NULL, NULL);
744 g_return_val_if_fail (GNUCASH_IS_SHEET(sheet), NULL);
746 block = gnucash_sheet_get_block (sheet, vcell_loc);
756 gnucash_sheet_get_style_from_table (
GnucashSheet *sheet,
764 g_return_val_if_fail (sheet != NULL, NULL);
765 g_return_val_if_fail (GNUCASH_IS_SHEET(sheet), NULL);
767 table = sheet->table;
769 vcell = gnc_table_get_virtual_cell (table, vcell_loc);
771 cursor = vcell->cellblock;
773 style = gnucash_sheet_get_style_from_cursor (sheet,
774 cursor->cursor_name);
778 return gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
782 gnucash_sheet_get_style_from_cursor (
GnucashSheet *sheet,
783 const char *cursor_name)
785 g_return_val_if_fail (sheet != NULL, NULL);
786 g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL);
791 return g_hash_table_lookup (sheet->cursor_styles, cursor_name);
802 g_return_if_fail (style != NULL);
811 g_return_if_fail (style != NULL);
815 if (style->refcount < 0)
816 g_warning (
"Unbalanced Style ref/unref");
826 gnc_header_widths_new (
void)
828 return g_hash_table_new (g_str_hash, g_str_equal);
832 header_width_destroy_helper (gpointer key, gpointer value, gpointer user_data)
836 g_free (wn->cell_name);
837 wn->cell_name = NULL;
843 gnc_header_widths_destroy (GNCHeaderWidths widths)
846 g_hash_table_foreach (widths, header_width_destroy_helper, NULL);
847 g_hash_table_destroy (widths);
851 gnc_header_widths_set_width (GNCHeaderWidths widths,
852 const char *cell_name,
857 g_return_if_fail (widths != NULL);
858 g_return_if_fail (cell_name != NULL);
860 wn = g_hash_table_lookup (widths, cell_name);
865 wn->cell_name = g_strdup (cell_name);
867 g_hash_table_insert (widths, wn->cell_name, wn);
874 gnc_header_widths_get_width (GNCHeaderWidths widths,
875 const char *cell_name)
879 g_return_val_if_fail (widths != NULL, 0);
881 wn = g_hash_table_lookup (widths, cell_name);
890 GNCHeaderWidths widths)
896 g_return_if_fail (sheet != NULL);
897 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
899 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
900 g_return_if_fail (style != NULL);
902 header = style->cursor;
903 g_return_if_fail (header != NULL);
905 for (row = 0; row < style->nrows; row++)
906 for (col = 0; col < style->ncols; col++)
911 cd = gnucash_style_get_cell_dimensions (style,
916 cell = gnc_cellblock_get_cell (header, row, col);
917 if (!cell || !cell->cell_name)
920 gnc_header_widths_set_width (widths,
928 GNCHeaderWidths widths)
934 g_return_if_fail (sheet != NULL);
935 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
937 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
938 g_return_if_fail (style != NULL);
940 header = style->cursor;
941 g_return_if_fail (header != NULL);
943 for (row = 0; row < style->nrows; row++)
944 for (col = 0; col < style->ncols; col++)
949 cd = gnucash_style_get_cell_dimensions (style,
952 cell = gnc_cellblock_get_cell (header, row, col);
953 if (!cell || !cell->cell_name)
956 cd->pixel_width = gnc_header_widths_get_width
957 (widths, cell->cell_name);
962 gnucash_style_init (
void)
#define ENTER(format, args...)
All type declarations for the whole Gnucash engine.
#define LEAVE(format, args...)
const gchar * QofLogModule