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