GnuCash c935c2f+
Loading...
Searching...
No Matches
gnucash-style.c
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 * configure the cursor styles
23 */
24
25#include <config.h>
26#include "gnucash-color.h"
27#include "gnucash-item-edit.h"
28#include "gnucash-sheet.h"
29#include "gnucash-sheetP.h"
30#include "gnucash-style.h"
31#include "gnc-engine.h" // For debugging, e.g. ENTER(), LEAVE()
32
34/* This static indicates the debugging module that this .o belongs to. */
35#define DEFAULT_STYLE_WIDTH 680
36
37
40/* This static indicates the debugging module that this .o belongs to. */
41static QofLogModule log_module = GNC_MOD_REGISTER;
42
43
46static gpointer
47style_get_key (SheetBlockStyle *style)
48{
49 static gint key;
50
51 key = style->cursor->num_rows;
52
53 return &key;
54}
55
56static gpointer
57style_create_key (SheetBlockStyle *style)
58{
59 gint key = style->cursor->num_rows;
60
61 gint *new_key = g_new(gint, 1);
62 *new_key = key;
63
64 return new_key;
65}
66
67static void
68cell_dimensions_construct (gpointer _cd, gpointer user_data)
69{
70 CellDimensions *cd = _cd;
71
72 cd->pixel_width = -1;
73 cd->can_span_over = TRUE;
74}
75
76
77static BlockDimensions *
78style_dimensions_new (SheetBlockStyle *style)
79{
80 BlockDimensions *dimensions;
81
82 dimensions = g_new0 (BlockDimensions, 1);
83
84 dimensions->nrows = style->nrows;
85 dimensions->ncols = style->ncols;
86
87 dimensions->cell_dimensions = g_table_new (sizeof (CellDimensions),
88 cell_dimensions_construct,
89 NULL, NULL);
90
91 g_table_resize (dimensions->cell_dimensions,
92 style->nrows, style->ncols);
93
94 return dimensions;
95}
96
97static void
98style_dimensions_destroy (BlockDimensions *dimensions)
99{
100 if (dimensions == NULL)
101 return;
102
103 dimensions->refcount--;
104
105 if (dimensions->refcount == 0)
106 {
107 g_table_destroy (dimensions->cell_dimensions);
108 dimensions->cell_dimensions = NULL;
109
110 g_free(dimensions);
111 }
112}
113
114
115static void
116gnucash_style_dimensions_init (GnucashSheet *sheet, SheetBlockStyle *style)
117{
118 BlockDimensions *dimensions;
119
120 dimensions = g_hash_table_lookup (sheet->dimensions_hash_table,
121 style_get_key (style));
122
123 if (!dimensions)
124 {
125 dimensions = style_dimensions_new (style);
126 g_hash_table_insert (sheet->dimensions_hash_table,
127 style_create_key (style), dimensions);
128 }
129
130 dimensions->refcount++;
131
132 style->dimensions = dimensions;
133}
134
135
137gnucash_style_get_cell_dimensions (SheetBlockStyle *style, int row, int col)
138{
139 if (style == NULL)
140 return NULL;
141 if (style->dimensions == NULL)
142 return NULL;
143 if (style->dimensions->cell_dimensions == NULL)
144 return NULL;
145
146 return g_table_index (style->dimensions->cell_dimensions, row, col);
147}
148
149static int
150compute_row_width (BlockDimensions *dimensions, int row, int col1, int col2)
151{
152 int j;
153 int width = 0;
154
155 col1 = MAX(0, col1);
156 col2 = MIN(col2, dimensions->ncols - 1);
157
158 for (j = col1; j <= col2; j++)
159 {
160 CellDimensions *cd;
161 cd = g_table_index (dimensions->cell_dimensions, row, j);
162
163 if (!cd)
164 continue;
165
166 width += cd->pixel_width;
167 }
168
169 return width;
170}
171
172
173/* This sets the initial sizes of the cells, based on the sample_text */
174static void
175set_dimensions_pass_one (GnucashSheet *sheet, CellBlock *cursor,
176 BlockDimensions *dimensions)
177{
178 CellDimensions *cd;
179 int row, col;
180 gint max_height = -1;
181 PangoLayout *layout;
182 GncItemEdit *item_edit = GNC_ITEM_EDIT(sheet->item_editor);
183
184 /* g_return_if_fail (font != NULL); */
185
186 for (row = 0; row < cursor->num_rows; row++)
187 {
188 for (col = 0; col < cursor->num_cols; col++)
189 {
190 int width;
191 char *text;
192 BasicCell *cell;
193
194 cd = g_table_index (dimensions->cell_dimensions,
195 row, col);
196
197 cell = gnc_cellblock_get_cell (cursor, row, col);
198 if (!cell || !cd)
199 continue;
200
201 text = cell->sample_text;
202 if (text)
203 cd->can_span_over = FALSE;
204
205 if (text)
206 {
207 layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text);
208 pango_layout_get_pixel_size (layout, &width, &cd->pixel_height);
209 g_object_unref (layout);
210 width += gnc_item_edit_get_margin (item_edit, left_right) +
211 gnc_item_edit_get_padding_border (item_edit, left_right);
212
213 // This is used on new popup cells to get the default
214 // width of text plus toggle button.
215 if (cell && cell->is_popup)
216 width += gnc_item_edit_get_button_width (item_edit) + 2; // + 2 for the button margin
217
218 cd->pixel_height += gnc_item_edit_get_margin (item_edit, top_bottom) +
219 gnc_item_edit_get_padding_border (item_edit, top_bottom);
220 }
221 else
222 {
223 width = 0;
224 cd->pixel_height = gnc_item_edit_get_margin (item_edit, top_bottom) +
225 gnc_item_edit_get_padding_border (item_edit, top_bottom);
226 }
227 // add 1 to cd->pixel_height to allow for a cell border
228 max_height = MAX(max_height, cd->pixel_height + 1);
229
230 if (cd->pixel_width > 0)
231 continue;
232
233 cd->pixel_width = MAX (cd->pixel_width, width);
234 }
235
236 dimensions->height += max_height;
237 }
238
239 for (row = 0; row < cursor->num_rows; row++)
240 {
241 for (col = 0; col < cursor->num_cols; col++)
242 {
243 cd = g_table_index (dimensions->cell_dimensions,
244 row, col);
245 if (!cd)
246 continue;
247
248 cd->pixel_height = max_height;
249 }
250 }
251}
252
253
254/* Now adjust things to make everything even. This code assumes that
255 * all cursors have the same number of columns!!! */
256static void
257set_dimensions_pass_two (GnucashSheet *sheet, int default_width)
258{
259 SheetBlockStyle *style;
260 GncItemEdit *item_edit = GNC_ITEM_EDIT(sheet->item_editor);
261 BlockDimensions *dimensions;
262 CellDimensions *cd;
263 GTable *cd_table;
264 CellBlock *cursor;
265 GList *cursors;
266 GList *node;
267
268 int num_cols;
269 int *widths;
270 int width;
271 int row, col;
272
273 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
274 dimensions = style->dimensions;
275 cd_table = dimensions->cell_dimensions;
276 cursor = style->cursor;
277
278 width = 0;
279 num_cols = cursor->num_cols;
280 widths = g_new0 (int, num_cols);
281
282 /* find header widths */
283 for (col = 0; col < num_cols; col++)
284 {
285 cd = g_table_index (cd_table, 0, col);
286
287 if (!cd)
288 continue;
289
290 widths[col] = cd->pixel_width;
291 width += cd->pixel_width;
292 }
293
294 if (width < default_width)
295 for (col = 0; col < num_cols; col++)
296 {
297 BasicCell *cell;
298
299 cell = gnc_cellblock_get_cell (cursor, 0, col);
300
301 if (!cell || !cell->expandable)
302 continue;
303
304 cd = g_table_index (cd_table, 0, col);
305
306 if (!cd)
307 continue;
308
309 cd->pixel_width += (default_width - width);
310 widths[col] = cd->pixel_width;
311
312 break;
313 }
314 else if (width > default_width && width == sheet->window_width)
315 {
316 for (col = 0; col < num_cols; col++)
317 {
318 BasicCell *cell;
319 const char *text;
320 int sample_width;
321 PangoLayout *layout;
322
323 cell = gnc_cellblock_get_cell (cursor, 0, col);
324
325 if (!cell || !cell->expandable)
326 continue;
327
328 cd = g_table_index (cd_table, 0, col);
329
330 if (!cd)
331 continue;
332
333 cd->pixel_width += (default_width - width);
334
335 text = cell->sample_text;
336 if (text)
337 {
338 layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text);
339 pango_layout_get_pixel_size (layout, &sample_width, NULL);
340 g_object_unref (layout);
341 /*sample_width = gdk_string_width (font, text);*/
342 sample_width += gnc_item_edit_get_margin (item_edit, left_right) +
343 gnc_item_edit_get_padding_border (item_edit, left_right);
344 }
345 else
346 sample_width = 0;
347
348 cd->pixel_width = MAX (cd->pixel_width, sample_width);
349
350 widths[col] = cd->pixel_width;
351
352 break;
353 }
354 }
355
356 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
357
358 /* adjust widths to be consistent */
359 for (node = cursors; node; node = node->next)
360 {
361 cursor = node->data;
362 style = gnucash_sheet_get_style_from_cursor
363 (sheet, cursor->cursor_name);
364 dimensions = style->dimensions;
365 cd_table = dimensions->cell_dimensions;
366
367 for (row = 0; row < cursor->num_rows; row++)
368 for (col = 0; col < num_cols; col++)
369 {
370 cd = g_table_index (cd_table, row, col);
371
372 if (!cd)
373 continue;
374
375 cd->pixel_width = widths[col];
376 }
377 }
378
379 /* now expand spanning cells */
380 for (node = cursors; node; node = node->next)
381 {
382 CellDimensions *cd_span;
383
384 cursor = node->data;
385 style = gnucash_sheet_get_style_from_cursor
386 (sheet, cursor->cursor_name);
387 dimensions = style->dimensions;
388 cd_table = dimensions->cell_dimensions;
389
390 for (row = 0; row < cursor->num_rows; row++)
391 {
392 cd_span = NULL;
393
394 for (col = 0; col < num_cols; col++)
395 {
396 BasicCell *cell;
397
398 cell = gnc_cellblock_get_cell (cursor,
399 row, col);
400 if (!cell)
401 continue;
402
403 cd = g_table_index (cd_table, row, col);
404
405 if (cell->span)
406 {
407 cd_span = cd;
408 continue;
409 }
410
411 if (!cd || !cd->can_span_over)
412 continue;
413
414 if (cd_span == NULL)
415 continue;
416
417 if (cell->sample_text != NULL)
418 {
419 cd_span = NULL;
420 continue;
421 }
422
423 if (cd->pixel_width <= 0)
424 continue;
425
426 cd_span->pixel_width += cd->pixel_width;
427 cd->pixel_width = 0;
428 }
429 }
430 }
431
432 g_free (widths);
433}
434
435gint
436gnucash_style_row_width(SheetBlockStyle *style, int row)
437{
438 BlockDimensions *dimensions;
439
440 dimensions = style->dimensions;
441
442 return compute_row_width(dimensions, row, 0, dimensions->ncols - 1);
443}
444
445static void
446compute_cell_origins_x (BlockDimensions *dimensions)
447{
448 int x;
449 int i, j;
450
451 for (i = 0; i < dimensions->nrows; i++)
452 {
453 x = 0;
454
455 for (j = 0; j < dimensions->ncols; j++)
456 {
457 CellDimensions *cd;
458
459 cd = g_table_index (dimensions->cell_dimensions, i, j);
460
461 if (!cd)
462 continue;
463
464 cd->origin_x = x;
465 x += cd->pixel_width;
466 }
467 }
468}
469
470static void
471compute_cell_origins_y (BlockDimensions *dimensions)
472{
473 CellDimensions *cd;
474 int y = 0;
475 int i, j;
476
477 for (i = 0; i < dimensions->nrows; i++)
478 {
479 for (j = 0; j < dimensions->ncols; j++)
480 {
481 cd = g_table_index (dimensions->cell_dimensions, i, j);
482
483 if (!cd)
484 continue;
485
486 cd->origin_y = y;
487 }
488 cd = g_table_index (dimensions->cell_dimensions, i, 0);
489
490 if (!cd)
491 continue;
492
493 y += cd->pixel_height;
494 }
495}
496
497/* Calculate the widths and offsets */
498static void
499set_dimensions_pass_three (GnucashSheet *sheet)
500{
501 GList *cursors;
502 GList *node;
503
504 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
505
506 for (node = cursors; node; node = node->next)
507 {
508 CellBlock *cursor = node->data;
509
510 SheetBlockStyle *style;
511 BlockDimensions *dimensions;
512
513 style = gnucash_sheet_get_style_from_cursor
514 (sheet, cursor->cursor_name);
515 dimensions = style->dimensions;
516
517 dimensions->width = compute_row_width (dimensions, 0, 0,
518 dimensions->ncols - 1);
519
520 compute_cell_origins_x (dimensions);
521 compute_cell_origins_y (dimensions);
522 }
523}
524
525static void
526styles_recompute_layout_dimensions (GnucashSheet *sheet, int default_width)
527{
528 CellBlock *cursor;
529 SheetBlockStyle *style;
530 BlockDimensions *dimensions;
531 GList *cursors;
532 GList *node;
533
534 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
535
536 for (node = cursors; node; node = node->next)
537 {
538 cursor = node->data;
539
540 style = gnucash_sheet_get_style_from_cursor
541 (sheet, cursor->cursor_name);
542
543 dimensions = style->dimensions;
544
545 dimensions->height = 0;
546 dimensions->width = default_width;
547
548 set_dimensions_pass_one (sheet, cursor, dimensions);
549 }
550
551 set_dimensions_pass_two (sheet, default_width);
552 set_dimensions_pass_three (sheet);
553}
554
555void
556gnucash_sheet_styles_set_dimensions (GnucashSheet *sheet, int default_width)
557{
558 g_return_if_fail (sheet != NULL);
559 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
560
561 styles_recompute_layout_dimensions (sheet, default_width);
562}
563
564gint
565gnucash_style_col_is_resizable (SheetBlockStyle *style, int col)
566{
567 if (col < 0 || col >= style->ncols)
568 return FALSE;
569
570 return TRUE;
571}
572
573void
574gnucash_sheet_set_col_width (GnucashSheet *sheet, int col, int width)
575{
576 CellDimensions *cd;
577 SheetBlockStyle *style;
578 int total;
579 int diff;
580
581 g_return_if_fail (sheet != NULL);
582 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
583 g_return_if_fail (col >= 0);
584
585 if (width < 0)
586 return;
587
588 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
589
590 g_return_if_fail (col < style->ncols);
591
592 cd = gnucash_style_get_cell_dimensions (style, 0, col);
593 if (!cd) return;
594
595 /* adjust the overall width of this style */
596 diff = cd->pixel_width - width;
597 cd->pixel_width = width;
598
599 total = MAX (sheet->window_width, sheet->width - diff);
600
601 set_dimensions_pass_two (sheet, total);
602 set_dimensions_pass_three (sheet);
603}
604
605
606void
607gnucash_sheet_styles_recompile(GnucashSheet *sheet)
608{
609}
610
611
612void
613gnucash_sheet_get_borders (GnucashSheet *sheet, VirtualLocation virt_loc,
614 PhysicalCellBorders *borders)
615{
616 SheetBlockStyle *style;
617 PhysicalCellBorderLineStyle line_style;
618
619 g_return_if_fail (sheet != NULL);
620 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
621
622 line_style = sheet->use_horizontal_lines ?
623 CELL_BORDER_LINE_NORMAL : CELL_BORDER_LINE_NONE;
624
625 borders->top = line_style;
626 borders->bottom = line_style;
627
628 line_style = sheet->use_vertical_lines ?
629 CELL_BORDER_LINE_NORMAL : CELL_BORDER_LINE_NONE;
630
631 borders->left = line_style;
632 borders->right = line_style;
633
634 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
635 if (style)
636 if (virt_loc.phys_col_offset == (style->ncols - 1))
637 borders->right = CELL_BORDER_LINE_NORMAL;
638
639 if (virt_cell_loc_equal (virt_loc.vcell_loc,
640 sheet->table->current_cursor_loc.vcell_loc))
641 {
642 borders->top = CELL_BORDER_LINE_NORMAL;
643 borders->bottom = CELL_BORDER_LINE_NORMAL;
644 }
645
646 gnc_table_get_borders (sheet->table, virt_loc, borders);
647}
648
649
650static SheetBlockStyle *
651gnucash_sheet_style_new (GnucashSheet *sheet, CellBlock *cursor)
652{
653 SheetBlockStyle *style;
654
655 g_return_val_if_fail (sheet != NULL, NULL);
656 g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL);
657 g_return_val_if_fail (cursor != NULL, NULL);
658
659 style = g_new0 (SheetBlockStyle, 1);
660
661 style->cursor = cursor;
662
663 style->nrows = cursor->num_rows;
664 style->ncols = cursor->num_cols;
665
666 gnucash_style_dimensions_init (sheet, style);
667
668 return style;
669}
670
671static void
672destroy_style_helper (gpointer key, gpointer value, gpointer user_data)
673{
674 char *cursor_name = key;
675 SheetBlockStyle *style = value;
676 GnucashSheet *sheet = user_data;
677
678 gnucash_sheet_style_unref (sheet, style);
679 g_free (cursor_name);
680}
681
682void
683gnucash_sheet_clear_styles (GnucashSheet *sheet)
684{
685 g_return_if_fail (sheet != NULL);
686 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
687
688 g_hash_table_foreach (sheet->cursor_styles,
689 destroy_style_helper, sheet);
690}
691
692void
693gnucash_sheet_create_styles (GnucashSheet *sheet)
694{
695 GList *cursors;
696 GList *node;
697
698 g_return_if_fail (sheet != NULL);
699 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
700
701 gnucash_sheet_clear_styles (sheet);
702
703 cursors = gnc_table_layout_get_cursors (sheet->table->layout);
704
705 for (node = cursors; node; node = node->next)
706 {
707 CellBlock *cursor = node->data;
708 SheetBlockStyle *style = gnucash_sheet_style_new (sheet, cursor);
709
710 gnucash_sheet_style_ref (sheet, style);
711 g_hash_table_insert (sheet->cursor_styles,
712 g_strdup (cursor->cursor_name),
713 style);
714 }
715}
716
717void
718gnucash_sheet_compile_styles (GnucashSheet *sheet)
719{
720 g_return_if_fail (sheet != NULL);
721 g_return_if_fail (GNUCASH_IS_SHEET (sheet));
722
723 ENTER("sheet=%p", sheet);
724
725 gnucash_sheet_styles_set_dimensions (sheet, DEFAULT_STYLE_WIDTH);
726
727 LEAVE(" ");
728}
729
730void
731gnucash_sheet_style_destroy (GnucashSheet *sheet, SheetBlockStyle *style)
732{
733 if (sheet == NULL)
734 return;
735 if (style == NULL)
736 return;
737
738 style->dimensions->refcount--;
739
740 if (style->dimensions->refcount == 0)
741 {
742 style_dimensions_destroy (style->dimensions);
743 g_hash_table_remove (sheet->dimensions_hash_table,
744 style_get_key (style));
745 }
746
747 g_free (style);
748}
749
750
751void
752gnucash_sheet_style_get_cell_pixel_rel_coords (SheetBlockStyle *style,
753 gint cell_row, gint cell_col,
754 gint *x, gint *y,
755 gint *w, gint *h)
756{
757 CellDimensions *cd;
758
759 g_return_if_fail (style != NULL);
760 g_return_if_fail (cell_row >= 0 && cell_row <= style->nrows);
761 g_return_if_fail (cell_col >= 0 && cell_col <= style->ncols);
762
763 cd = gnucash_style_get_cell_dimensions (style, cell_row, cell_col);
764 if (!cd) return;
765
766 *x = cd->origin_x;
767 *y = cd->origin_y;
768 *h = cd->pixel_height;
769 *w = cd->pixel_width;
770}
771
772
773SheetBlockStyle *
774gnucash_sheet_get_style (GnucashSheet *sheet, VirtualCellLocation vcell_loc)
775{
776 SheetBlock *block;
777
778 g_return_val_if_fail (sheet != NULL, NULL);
779 g_return_val_if_fail (GNUCASH_IS_SHEET(sheet), NULL);
780
781 block = gnucash_sheet_get_block (sheet, vcell_loc);
782
783 if (block)
784 return block->style;
785 else
786 return NULL;
787}
788
789
790SheetBlockStyle *
791gnucash_sheet_get_style_from_table (GnucashSheet *sheet,
792 VirtualCellLocation vcell_loc)
793{
794 Table *table;
795 VirtualCell *vcell;
796 CellBlock *cursor;
797 SheetBlockStyle *style;
798
799 g_return_val_if_fail (sheet != NULL, NULL);
800 g_return_val_if_fail (GNUCASH_IS_SHEET(sheet), NULL);
801
802 table = sheet->table;
803
804 vcell = gnc_table_get_virtual_cell (table, vcell_loc);
805
806 if (!vcell)
807 return NULL;
808
809 cursor = vcell->cellblock;
810
811 style = gnucash_sheet_get_style_from_cursor (sheet,
812 cursor->cursor_name);
813 if (style)
814 return style;
815
816 return gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
817}
818
819SheetBlockStyle *
820gnucash_sheet_get_style_from_cursor (GnucashSheet *sheet,
821 const char *cursor_name)
822{
823 g_return_val_if_fail (sheet != NULL, NULL);
824 g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL);
825
826 if (!cursor_name)
827 return NULL;
828
829 return g_hash_table_lookup (sheet->cursor_styles, cursor_name);
830}
831
832/*
833 * For now, refcounting doesn't do much, but later we may want to
834 * destroy styles
835 */
836
837void
838gnucash_sheet_style_ref (GnucashSheet *sheet, SheetBlockStyle *style)
839{
840 g_return_if_fail (style != NULL);
841
842 style->refcount++;
843}
844
845
846void
847gnucash_sheet_style_unref (GnucashSheet *sheet, SheetBlockStyle *style)
848{
849 g_return_if_fail (style != NULL);
850
851 style->refcount--;
852
853 if (style->refcount == 0)
854 gnucash_sheet_style_destroy (sheet, style);
855}
856
857typedef struct
858{
859 char *cell_name;
860 int width;
861} WidthNode;
862
863GNCHeaderWidths
864gnc_header_widths_new (void)
865{
866 return g_hash_table_new (g_str_hash, g_str_equal);
867}
868
869static void
870header_width_destroy_helper (gpointer key, gpointer value, gpointer user_data)
871{
872 WidthNode *wn = value;
873
874 g_free (wn->cell_name);
875 wn->cell_name = NULL;
876
877 g_free (wn);
878}
879
880void
881gnc_header_widths_destroy (GNCHeaderWidths widths)
882{
883 if (!widths) return;
884 g_hash_table_foreach (widths, header_width_destroy_helper, NULL);
885 g_hash_table_destroy (widths);
886}
887
888void
889gnc_header_widths_set_width (GNCHeaderWidths widths,
890 const char *cell_name,
891 int width)
892{
893 WidthNode *wn;
894
895 g_return_if_fail (widths != NULL);
896 g_return_if_fail (cell_name != NULL);
897
898 wn = g_hash_table_lookup (widths, cell_name);
899 if (!wn)
900 {
901 wn = g_new0 (WidthNode, 1);
902
903 wn->cell_name = g_strdup (cell_name);
904
905 g_hash_table_insert (widths, wn->cell_name, wn);
906 }
907
908 wn->width = width;
909}
910
911int
912gnc_header_widths_get_width (GNCHeaderWidths widths,
913 const char *cell_name)
914{
915 WidthNode *wn;
916
917 g_return_val_if_fail (widths != NULL, 0);
918
919 wn = g_hash_table_lookup (widths, cell_name);
920 if (!wn)
921 return 0;
922
923 return wn->width;
924}
925
926void
927gnucash_sheet_get_header_widths (GnucashSheet *sheet,
928 GNCHeaderWidths widths)
929{
930 SheetBlockStyle *style;
931 CellBlock *header;
932 int row, col;
933
934 g_return_if_fail (sheet != NULL);
935 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
936
937 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
938 g_return_if_fail (style != NULL);
939
940 header = style->cursor;
941 g_return_if_fail (header != NULL);
942
943 for (row = 0; row < style->nrows; row++)
944 for (col = 0; col < style->ncols; col++)
945 {
946 CellDimensions *cd;
947 BasicCell *cell;
948
949 cd = gnucash_style_get_cell_dimensions (style,
950 row, col);
951 if (cd == NULL)
952 continue;
953
954 cell = gnc_cellblock_get_cell (header, row, col);
955 if (!cell || !cell->cell_name)
956 continue;
957
958 gnc_header_widths_set_width (widths,
959 cell->cell_name,
960 cd->pixel_width);
961 }
962}
963
964void
965gnucash_sheet_set_header_widths (GnucashSheet *sheet,
966 GNCHeaderWidths widths)
967{
968 SheetBlockStyle *style;
969 CellBlock *header;
970 int row, col;
971
972 g_return_if_fail (sheet != NULL);
973 g_return_if_fail (GNUCASH_IS_SHEET(sheet));
974
975 style = gnucash_sheet_get_style_from_cursor (sheet, CURSOR_HEADER);
976 g_return_if_fail (style != NULL);
977
978 header = style->cursor;
979 g_return_if_fail (header != NULL);
980
981 for (row = 0; row < style->nrows; row++)
982 for (col = 0; col < style->ncols; col++)
983 {
984 CellDimensions *cd;
985 BasicCell *cell;
986
987 cd = gnucash_style_get_cell_dimensions (style,
988 row, col);
989
990 cell = gnc_cellblock_get_cell (header, row, col);
991 if (!cell || !cell->cell_name || !cd)
992 continue;
993
994 cd->pixel_width = gnc_header_widths_get_width
995 (widths, cell->cell_name);
996 }
997}
998
999gboolean
1000gnucash_style_init (void)
1001{
1002 return TRUE;
1003}
1004
1005
All type declarations for the whole Gnucash engine.
Convenience wrapper around GdkRGBA for use in Register Gnome classes.
Public declarations for GncItemEdit class.
Private declarations for GnucashSheet class.
Public declarations of GnucashRegister class.
Styling functions for RegisterGnome.
BasicCell * gnc_cellblock_get_cell(CellBlock *cellblock, int row, int col)
Retrieve the Cell at the specified coordinates.
Definition cellblock.c:109
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
void g_table_destroy(GTable *gtable)
Free the table and all associated table elements.
Definition gtable.c:69
void g_table_resize(GTable *gtable, int rows, int cols)
Resize the table, allocating and deallocating extra table members if needed.
Definition gtable.c:104
gpointer g_table_index(GTable *gtable, int row, int col)
Return the element at the given row and column.
Definition gtable.c:84
GTable * g_table_new(guint entry_size, g_table_entry_constructor constructor, g_table_entry_destroyer destroyer, gpointer user_data)
Create a new table with the given entry constructor and destroyer.
Definition gtable.c:44
#define CURSOR_HEADER
Standard Cursor Names.
VirtualCell * gnc_table_get_virtual_cell(Table *table, VirtualCellLocation vcell_loc)
returns the virtual cell associated with a particular virtual location.
SheetBlockStyle * style
The style for this block.
holds information about each virtual cell.