1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * sheet-autofill.c: Provides the autofill features
6 * Miguel de Icaza (miguel@kernel.org), 1998
7 * Jody Goldberg (jody@gnome.org), 1999-2006
8 * Copyright (C) 1999-2009 Morten Welinder (terra@gnome.org)
10 #include <gnumeric-config.h>
11 #include <glib/gi18n-lib.h>
13 #include "sheet-autofill.h"
19 #include "sheet-style.h"
21 #include "gnm-datetime.h"
24 #include "sheet-merge.h"
25 #include "gnm-format.h"
26 #include <goffice/goffice.h>
32 /* ------------------------------------------------------------------------- */
34 static char *month_names_long
[12 + 1];
35 static char *month_names_short
[12 + 1];
36 static char *weekday_names_long
[7 + 1];
37 static char *weekday_names_short
[7 + 1];
38 static char *quarters
[4 + 1];
39 static gboolean has_quarters
;
42 * gnm_autofill_init: (skip)
45 gnm_autofill_init (void)
49 char const *qtemplate
;
51 for (m
= 1; m
<= 12; m
++) {
52 month_names_long
[m
- 1] = go_date_month_name (m
, FALSE
);
53 month_names_short
[m
- 1] = go_date_month_name (m
, TRUE
);
55 for (wd
= 1; wd
<= 7; wd
++) {
56 weekday_names_long
[wd
- 1] = go_date_weekday_name (wd
, FALSE
);
57 weekday_names_short
[wd
- 1] = go_date_weekday_name (wd
, TRUE
);
60 /* xgettext: This is a C format string where %d will be replaced
61 by 1, 2, 3, or 4. A year will then be appended and we'll get
62 something like 3Q2005. If that makes no sense in your language,
63 translate to the empty string. */
65 has_quarters
= (qtemplate
[0] != 0);
68 for (q
= 1; q
<= 4; q
++)
69 quarters
[q
- 1] = g_strdup_printf (qtemplate
, q
);
74 * gnm_autofill_shutdown: (skip)
77 gnm_autofill_shutdown (void)
83 for (m
= 1; m
<= 12; m
++) {
84 g_free (month_names_long
[m
- 1]);
85 g_free (month_names_short
[m
- 1]);
87 for (wd
= 1; wd
<= 7; wd
++) {
88 g_free (weekday_names_long
[wd
- 1]);
89 g_free (weekday_names_short
[wd
- 1]);
91 for (q
= 1; q
<= 4; q
++)
92 g_free (quarters
[q
- 1]);
95 /* ------------------------------------------------------------------------- */
103 typedef struct _AutoFiller AutoFiller
;
106 AutoFillerStatus status
;
109 void (*finalize
) (AutoFiller
*af
);
111 /* Given a new cell, adapt filler to that. */
112 void (*teach_cell
) (AutoFiller
*af
, const GnmCell
*cell
, int n
);
114 /* Set cell to the value of the nth sequence member. */
115 void (*set_cell
) (AutoFiller
*af
, GnmCell
*cell
, int n
);
117 /* Hint of what will be the nth element. */
118 char * (*hint
) (AutoFiller
*af
, GnmCellPos
*pos
, int n
);
122 af_finalize (AutoFiller
*af
)
127 /* ------------------------------------------------------------------------- */
129 * Arithmetic sequences:
133 * 1-Jan-2009, 2-Jan-2009, 3-Jan-2009, ...
134 * 1-Jan-2009, 8-Jan-2009, 15-Jan-2009, ...
135 * 00:00, 00:30, 01:00, ...
141 gboolean singleton
; /* Missing step becomes 1. */
142 gnm_float base
, step
;
144 GODateConventions
const *dateconv
;
145 } AutoFillerArithmetic
;
148 afa_finalize (AutoFiller
*af
)
150 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
151 go_format_unref (afa
->format
);
156 afa_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
158 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
159 GnmValue
*value
= cell
? cell
->value
: NULL
;
163 gnm_cell_has_expr (cell
) ||
164 !VALUE_IS_NUMBER (value
) ||
165 VALUE_IS_BOOLEAN (value
)) {
166 af
->status
= AFS_ERROR
;
170 f
= value_get_as_float (value
);
174 afa
->dateconv
= sheet_date_conv (cell
->base
.sheet
);
176 if (afa
->singleton
) {
178 af
->status
= AFS_READY
;
180 if (VALUE_FMT (value
))
181 afa
->format
= go_format_ref (VALUE_FMT (value
));
184 afa
->step
= f
- afa
->base
;
185 af
->status
= AFS_READY
;
188 gnm_float step2
= (f
- afa
->base
) / n
;
189 gnm_float step_sum
= gnm_abs (afa
->step
) + gnm_abs (step2
);
190 gnm_float err
= step_sum
191 ? gnm_abs (afa
->step
- step2
) / step_sum
193 /* Be fairly lenient: */
194 if (err
> (n
+ 64) * GNM_EPSILON
) {
195 af
->status
= AFS_ERROR
;
203 afa_compute (AutoFillerArithmetic
*afa
, int n
)
205 gnm_float f
= afa
->base
+ n
* afa
->step
;
206 GnmValue
*v
= value_new_float (f
);
208 value_set_fmt (v
, afa
->format
);
213 afa_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
215 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
216 GnmValue
*v
= afa_compute (afa
, n
);
217 gnm_cell_set_value (cell
, v
);
221 afa_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
223 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
224 GnmValue
*v
= afa_compute (afa
, n
);
225 char *res
= format_value (NULL
, v
, -1, afa
->dateconv
);
231 auto_filler_arithmetic (gboolean singleton
)
233 AutoFillerArithmetic
*res
= g_new (AutoFillerArithmetic
, 1);
235 res
->filler
.status
= AFS_INCOMPLETE
;
236 res
->filler
.priority
= 100;
237 res
->filler
.finalize
= afa_finalize
;
238 res
->filler
.teach_cell
= afa_teach_cell
;
239 res
->filler
.set_cell
= afa_set_cell
;
240 res
->filler
.hint
= afa_hint
;
242 res
->dateconv
= NULL
;
243 res
->singleton
= singleton
;
248 /* ------------------------------------------------------------------------- */
251 gnm_float base
, step
;
252 GString
*prefix
, *suffix
;
253 gboolean fixed_length
;
254 int base_phase
, phases
;
260 as_finalize (ArithString
*as
)
263 g_string_free (as
->prefix
, TRUE
);
265 g_string_free (as
->suffix
, TRUE
);
269 as_check_prefix_suffix (ArithString
*as
, char const *s
, gsize slen
)
272 if (slen
< as
->prefix
->len
||
273 memcmp (s
, as
->prefix
->str
, as
->prefix
->len
) != 0)
275 s
+= as
->prefix
->len
;
276 slen
-= as
->prefix
->len
;
280 if (slen
< as
->suffix
->len
||
281 memcmp (s
+ slen
- as
->suffix
->len
,
283 as
->suffix
->len
) != 0)
291 as_compute_val (ArithString
*as
, int n
)
293 int pn
= (n
* as
->step
+ as
->base_phase
) / as
->phases
;
294 gnm_float f
= as
->base
+ pn
;
295 if (as
->fixed_length
)
296 f
= gnm_fmod (f
, as
->p10
);
301 as_compute (ArithString
*as
, int n
)
303 gnm_float f
= as_compute_val (as
, n
);
304 char const *prefix
= as
->prefix
? as
->prefix
->str
: "";
305 char const *suffix
= as
->suffix
? as
->suffix
->str
: "";
307 if (as
->fixed_length
) {
308 return g_strdup_printf ("%s%0*.0" GNM_FORMAT_f
"%s",
313 return g_strdup_printf ("%s%.0" GNM_FORMAT_f
"%s",
321 as_teach_first (ArithString
*as
, char const *s
)
326 for (pl
= 0; s
[pl
]; pl
++) {
327 if (g_ascii_isdigit (s
[pl
]))
329 if (!as
->fixed_length
&&
330 (s
[pl
] == '+' || s
[pl
] == '-') &&
331 g_ascii_isdigit (s
[pl
+ 1]))
339 g_string_append_len (as
->prefix
, s
, pl
);
341 return TRUE
; /* No prefix allowed. */
344 as
->base
= strtol (s
+ pl
, &end
, 10);
350 g_string_append (as
->suffix
, end
);
352 return TRUE
; /* No suffix allowed. */
355 as
->numlen
= end
- (s
+ pl
);
356 as
->p10
= gnm_pow10 (as
->numlen
);
362 as_teach_rest (ArithString
*as
, char const *s
, int n
, int phase
)
364 gsize slen
= strlen (s
);
367 char const *s2
= s
+ (as
->prefix
? as
->prefix
->len
: 0);
369 if (as_check_prefix_suffix (as
, s
, slen
))
372 if (g_ascii_isspace (*s2
))
376 if (as
->fixed_length
) {
377 if (!g_ascii_isdigit (*s2
))
379 val
= strtol (s2
, &end
, 10);
380 if (as
->numlen
!= (gsize
)(end
- s2
))
384 * Verify no leading zero so the fixed-length
385 * version gets a chance.
388 if (!g_ascii_isdigit (*s3
))
390 if (s3
[0] == '0' && g_ascii_isdigit (s3
[1]))
392 val
= strtol (s2
, &end
, 10);
395 if (errno
== ERANGE
|| end
!= s
+ slen
- (as
->suffix
? as
->suffix
->len
: 0))
399 as
->step
= (val
- as
->base
) * as
->phases
+ (phase
- as
->base_phase
);
400 if (as
->fixed_length
&& as
->step
< 0)
401 as
->step
+= as
->p10
* as
->phases
;
403 gnm_float f
= as_compute_val (as
, n
);
404 if (gnm_abs (f
- val
) > 0.5)
411 /* ------------------------------------------------------------------------- */
414 * Arithmetic sequences in strings:
416 * "Foo 1", "Foo 2", "Foo 3", ...
417 * "1 Bar", "3 Bar", "5 Bar", ...
418 * "Fall '99", "Fall '00", "Fall '01", ...
424 gboolean singleton
; /* Missing step becomes 1. */
426 } AutoFillerNumberString
;
429 afns_finalize (AutoFiller
*af
)
431 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
432 as_finalize (&afns
->as
);
437 afns_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
439 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
440 GnmValue
*value
= cell
? cell
->value
: NULL
;
444 gnm_cell_has_expr (cell
) ||
445 !VALUE_IS_STRING (value
)) {
447 af
->status
= AFS_ERROR
;
451 s
= value_peek_string (value
);
454 if (as_teach_first (&afns
->as
, s
))
458 af
->status
= AFS_READY
;
460 if (as_teach_rest (&afns
->as
, s
, n
, 0))
463 af
->status
= AFS_READY
;
468 afns_compute (AutoFillerNumberString
*afns
, int n
)
470 return as_compute (&afns
->as
, n
);
474 afns_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
476 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
477 char *s
= afns_compute (afns
, n
);
478 gnm_cell_set_value (cell
, value_new_string_nocopy (s
));
482 afns_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
484 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
485 return afns_compute (afns
, n
);
489 auto_filler_number_string (gboolean singleton
, gboolean fixed_length
)
491 AutoFillerNumberString
*res
= g_new (AutoFillerNumberString
, 1);
493 res
->filler
.status
= AFS_INCOMPLETE
;
494 res
->filler
.priority
= fixed_length
? 9 : 10;
495 res
->filler
.finalize
= afns_finalize
;
496 res
->filler
.teach_cell
= afns_teach_cell
;
497 res
->filler
.set_cell
= afns_set_cell
;
498 res
->filler
.hint
= afns_hint
;
499 res
->singleton
= singleton
;
500 res
->as
.fixed_length
= fixed_length
;
501 res
->as
.prefix
= g_string_new (NULL
);
502 res
->as
.suffix
= g_string_new (NULL
);
503 res
->as
.base_phase
= 0;
509 /* ------------------------------------------------------------------------- */
513 * 1-Jan-2009, 1-Feb-2009, 1-Mar-2009, ...
514 * 31-Jan-2009, 28-Feb-2009, 31-Mar-2009, ...
515 * 1-Jan-2009, 1-Jan-2010, 1-Jan-2011, ...
521 GODateConventions
const *dateconv
;
525 gboolean end_of_month
, same_of_month
;
529 afm_finalize (AutoFiller
*af
)
531 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
532 go_format_unref (afm
->format
);
537 afm_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
539 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
540 GnmValue
*value
= cell
? cell
->value
: NULL
;
544 if (value
== NULL
|| gnm_cell_has_expr (cell
)) {
546 af
->status
= AFS_ERROR
;
550 sf
= gnm_cell_get_format (cell
);
551 if (gnm_format_is_date_for_value (sf
, value
) != 1)
554 afm
->dateconv
= sheet_date_conv (cell
->base
.sheet
);
555 if (!datetime_value_to_g (&d
, value
, afm
->dateconv
))
558 if (!g_date_is_last_of_month (&d
))
559 afm
->end_of_month
= FALSE
;
562 if (VALUE_FMT (value
))
563 afm
->format
= go_format_ref (VALUE_FMT (value
));
566 int year
= g_date_get_year (&d
);
567 int month
= g_date_get_month (&d
);
568 int day
= g_date_get_day (&d
);
571 if (day
!= g_date_get_day (&afm
->base
))
572 afm
->same_of_month
= FALSE
;
574 if (!afm
->same_of_month
&& !afm
->end_of_month
)
577 nmonths
= 12 * (year
- g_date_get_year (&afm
->base
)) +
578 (month
- g_date_get_month (&afm
->base
));
580 afm
->nmonths
= nmonths
;
581 else if (nmonths
!= afm
->nmonths
* n
)
584 af
->status
= AFS_READY
;
589 afm_compute (AutoFillerMonth
*afm
, int n
)
594 gnm_date_add_months (&d
, n
* afm
->nmonths
);
596 if (!g_date_valid (&d
) || g_date_get_year (&d
) > 9999)
599 if (afm
->end_of_month
) {
600 int year
= g_date_get_year (&d
);
601 int month
= g_date_get_month (&d
);
602 g_date_set_day (&d
, g_date_get_days_in_month (month
, year
));
605 v
= value_new_int (go_date_g_to_serial (&d
, afm
->dateconv
));
607 value_set_fmt (v
, afm
->format
);
612 afm_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
614 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
615 GnmValue
*v
= afm_compute (afm
, n
);
618 gnm_cell_set_value (cell
, v
);
621 eval_pos_init_cell (&ep
, cell
);
622 gnm_cell_set_value (cell
, value_new_error_VALUE (&ep
));
627 afm_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
629 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
630 GnmValue
*v
= afm_compute (afm
, n
);
634 res
= format_value (NULL
, v
, -1, afm
->dateconv
);
642 auto_filler_month (void)
644 AutoFillerMonth
*res
= g_new (AutoFillerMonth
, 1);
646 res
->filler
.status
= AFS_INCOMPLETE
;
647 res
->filler
.priority
= 200;
648 res
->filler
.finalize
= afm_finalize
;
649 res
->filler
.teach_cell
= afm_teach_cell
;
650 res
->filler
.set_cell
= afm_set_cell
;
651 res
->filler
.hint
= afm_hint
;
653 res
->dateconv
= NULL
;
654 res
->end_of_month
= TRUE
;
655 res
->same_of_month
= TRUE
;
660 /* ------------------------------------------------------------------------- */
666 gboolean with_number
;
671 afl_finalize (AutoFiller
*af
)
673 AutoFillerList
*afl
= (AutoFillerList
*)af
;
674 as_finalize (&afl
->as
);
679 afl_compute_phase (AutoFillerList
*afl
, int n
)
681 return (int)(n
* afl
->as
.step
+ afl
->as
.base_phase
) %
686 afl_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
688 AutoFillerList
*afl
= (AutoFillerList
*)af
;
689 GnmValue
*value
= cell
? cell
->value
: NULL
;
695 gnm_cell_has_expr (cell
) ||
696 !VALUE_IS_STRING (value
)) {
698 af
->status
= AFS_ERROR
;
702 s
= value_peek_string (value
);
703 for (ph
= 0; ph
< afl
->as
.phases
; ph
++) {
704 char const *e
= afl
->list
[ph
];
706 /* This isn't UTF-8 pretty. */
707 /* This isn't case pretty. */
708 /* This won't work if one list item is a prefix of another. */
709 if (strncmp (s
, e
, elen
) == 0)
712 if (ph
== afl
->as
.phases
)
716 afl
->as
.base_phase
= ph
;
718 if (afl
->with_number
) {
719 afl
->as
.prefix
= g_string_new (NULL
);
720 afl
->as
.suffix
= g_string_new (NULL
);
721 if (as_teach_first (&afl
->as
, s
+ elen
))
728 if (afl
->with_number
) {
729 if (as_teach_rest (&afl
->as
, s
+ elen
, n
, ph
))
736 int step
= ph
- afl
->as
.base_phase
;
740 step
+= afl
->as
.phases
;
743 if (ph
!= afl_compute_phase (afl
, n
))
748 af
->status
= AFS_READY
;
753 afl_compute (AutoFillerList
*afl
, int n
)
755 GString
*res
= g_string_new (afl
->list
[afl_compute_phase (afl
, n
)]);
757 if (afl
->with_number
) {
758 char *s
= as_compute (&afl
->as
, n
);
759 g_string_append (res
, s
);
763 return g_string_free (res
, FALSE
);
767 afl_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
769 AutoFillerList
*afl
= (AutoFillerList
*)af
;
770 char *str
= afl_compute (afl
, n
);
771 GnmValue
*val
= value_new_string_nocopy (str
);
772 gnm_cell_set_value (cell
, val
);
776 afl_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
778 AutoFillerList
*afl
= (AutoFillerList
*)af
;
779 return afl_compute (afl
, n
);
783 auto_filler_list (char **list
, int prio
, gboolean with_number
)
785 AutoFillerList
*res
= g_new (AutoFillerList
, 1);
787 res
->filler
.status
= AFS_INCOMPLETE
;
788 res
->filler
.priority
= prio
;
789 res
->filler
.finalize
= afl_finalize
;
790 res
->filler
.teach_cell
= afl_teach_cell
;
791 res
->filler
.set_cell
= afl_set_cell
;
792 res
->filler
.hint
= afl_hint
;
794 res
->with_number
= with_number
;
795 res
->as
.phases
= g_strv_length (list
);
796 res
->as
.fixed_length
= TRUE
;
797 res
->as
.prefix
= NULL
;
798 res
->as
.suffix
= NULL
;
803 /* ------------------------------------------------------------------------- */
810 const GnmCell
** cells
;
814 afc_finalize (AutoFiller
*af
)
816 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
822 afc_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
824 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
825 afe
->cells
[n
] = cell
;
826 if (n
== afe
->size
- 1) {
827 /* This actually includes the all-empty case. */
828 af
->status
= AFS_READY
;
833 afc_set_cell_hint (AutoFiller
*af
, GnmCell
*cell
, GnmCellPos
const *pos
,
834 int n
, gboolean doit
)
836 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
837 GnmCell
const *src
= afe
->cells
[n
% afe
->size
];
839 if (src
&& gnm_cell_has_expr (src
)) {
840 GnmExprRelocateInfo rinfo
;
841 GnmExprTop
const *texpr
;
842 GnmExprTop
const *src_texpr
= src
->base
.texpr
;
843 Sheet
*sheet
= src
->base
.sheet
;
845 /* Arrays are always assigned fully at the corner. */
846 if (gnm_expr_top_is_array_elem (src_texpr
, NULL
, NULL
))
849 rinfo
.reloc_type
= GNM_EXPR_RELOCATE_MOVE_RANGE
;
850 rinfo
.target_sheet
= rinfo
.origin_sheet
= NULL
;
851 rinfo
.col_offset
= rinfo
.row_offset
= 0;
852 rinfo
.origin
.start
= rinfo
.origin
.end
= *pos
;
853 parse_pos_init (&rinfo
.pos
, sheet
->workbook
, sheet
,
856 texpr
= gnm_expr_top_relocate (src_texpr
, &rinfo
, FALSE
);
858 /* Clip arrays that are only partially copied. */
859 if (gnm_expr_top_is_array_corner (src_texpr
)) {
860 GnmExpr
const *aexpr
;
861 int limit_x
= afe
->last
.col
- pos
->col
+ 1;
862 int limit_y
= afe
->last
.row
- pos
->row
+ 1;
865 gnm_expr_top_get_array_size (texpr
, &cols
, &rows
);
866 cols
= MIN (limit_x
, cols
);
867 rows
= MIN (limit_y
, rows
);
870 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (texpr
));
871 gnm_expr_top_unref (texpr
);
873 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr
));
876 gnm_cell_set_array_formula
878 pos
->col
, cell
->pos
.row
,
879 pos
->col
+ (cols
- 1),
880 pos
->row
+ (rows
- 1),
881 gnm_expr_top_new (aexpr
));
883 res
= gnm_expr_as_string (aexpr
,
886 gnm_expr_free (aexpr
);
890 gnm_cell_set_expr (cell
, texpr
);
892 res
= gnm_expr_top_as_string (texpr
,
895 gnm_expr_top_unref (texpr
);
898 gnm_cell_set_expr (cell
, src_texpr
);
900 res
= gnm_expr_top_as_string (src_texpr
,
906 gnm_cell_set_value (cell
, value_dup (src
->value
));
908 Sheet
const *sheet
= src
->base
.sheet
;
909 GODateConventions
const *dateconv
=
910 sheet_date_conv (sheet
);
911 GOFormat
const *format
= gnm_cell_get_format (src
);
912 return format_value (format
, src
->value
, -1,
917 sheet_cell_remove (cell
->base
.sheet
, cell
, TRUE
, TRUE
);
919 res
= g_strdup (_("(empty)"));
926 afc_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
928 afc_set_cell_hint (af
, cell
, &cell
->pos
, n
, TRUE
);
932 afc_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
934 return afc_set_cell_hint (af
, NULL
, pos
, n
, FALSE
);
938 auto_filler_copy (int size
, guint last_col
, guint last_row
)
940 AutoFillerCopy
*res
= g_new (AutoFillerCopy
, 1);
942 res
->filler
.status
= AFS_INCOMPLETE
;
943 res
->filler
.priority
= 1;
944 res
->filler
.finalize
= afc_finalize
;
945 res
->filler
.teach_cell
= afc_teach_cell
;
946 res
->filler
.set_cell
= afc_set_cell
;
947 res
->filler
.hint
= afc_hint
;
949 res
->last
.col
= last_col
;
950 res
->last
.row
= last_row
;
951 res
->cells
= g_new0 (GnmCell
const *, size
);
956 /* ------------------------------------------------------------------------- */
959 calc_steps (const GnmRange
*r
, int col_inc
, int row_inc
)
963 ? range_width (r
) / ABS (col_inc
)
964 : range_height (r
) / ABS (row_inc
);
971 * (base_col,base_row): start of source area.
972 * (col_inc,row_inc): direction of fill.
973 * count_max: size of source+fill area in direction of fill.
974 * region_size: size of source area in direction of fill.
975 * (last_col,last_row): last cell of entire area being filled.
979 sheet_autofill_dir (Sheet
*sheet
, gboolean singleton
,
980 int base_col
, int base_row
,
983 int col_inc
, int row_inc
,
984 int last_col
, int last_row
,
987 GList
*fillers
= NULL
;
989 int i
, j
, true_region_size
;
990 AutoFiller
*af
= NULL
;
991 GnmStyle
const **styles
;
992 GnmRange
const **merges
;
997 if (count_max
<= 0 || region_size
<= 0)
1001 * These are both indexed by cell number in the sequence we see
1002 * cells. I.e., they go 0, 1, 2, ... no matter what way we fill
1003 * and no matter if some cells are merged.
1005 * The allocations may be larger than we need, but we don't know
1006 * the right size yet.
1008 styles
= doit
? g_new0 (GnmStyle
const *, region_size
) : NULL
;
1009 merges
= g_new0 (GnmRange
const *, region_size
);
1012 * i counts rows/cols.
1013 * j follows, but skips hidden parts of merged cells.
1017 * Pass 1: Have a look at the merges. We always go right or down
1020 merge_size
= g_new0 (int, region_size
);
1021 reverse
= (col_inc
< 0 || row_inc
< 0);
1023 while (i
< region_size
) {
1024 int i2
= (reverse
? region_size
- 1 - i
: i
);
1025 int j2
= (reverse
? /*true_*/region_size
- 1 - j
: j
);
1026 int col2
= base_col
+ i2
* col_inc
;
1027 int row2
= base_row
+ i2
* row_inc
;
1032 styles
[j2
] = sheet_style_get (sheet
, col2
, row2
);
1033 gnm_style_ref (styles
[j2
]);
1038 merges
[j2
] = gnm_sheet_merge_contains_pos (sheet
, &pos
);
1039 di
= calc_steps (merges
[j2
], col_inc
, row_inc
);
1040 merge_size
[j2
] = di
- 1;
1044 true_region_size
= j
;
1046 /* We didn't know true_region_size up there. Patch up things. */
1048 memmove (merge_size
,
1049 merge_size
+ (region_size
- true_region_size
),
1050 true_region_size
* sizeof (*merge_size
));
1052 merges
+ (region_size
- true_region_size
),
1053 true_region_size
* sizeof (*merges
));
1056 styles
+ (region_size
- true_region_size
),
1057 true_region_size
* sizeof (*styles
));
1060 fillers
= g_list_prepend
1061 (fillers
, auto_filler_arithmetic (singleton
));
1062 fillers
= g_list_prepend
1063 (fillers
, auto_filler_number_string (singleton
, TRUE
));
1064 fillers
= g_list_prepend
1065 (fillers
, auto_filler_number_string (singleton
, FALSE
));
1066 fillers
= g_list_prepend
1067 (fillers
, auto_filler_month ());
1068 fillers
= g_list_prepend
1069 (fillers
, auto_filler_copy (true_region_size
,
1070 last_col
, last_row
));
1071 fillers
= g_list_prepend (fillers
, auto_filler_list (quarters
, 50, TRUE
));
1073 fillers
= g_list_prepend
1074 (fillers
, auto_filler_list (month_names_long
, 61, TRUE
));
1075 fillers
= g_list_prepend
1076 (fillers
, auto_filler_list (month_names_short
, 51, TRUE
));
1077 fillers
= g_list_prepend
1078 (fillers
, auto_filler_list (month_names_long
, 61, FALSE
));
1079 fillers
= g_list_prepend
1080 (fillers
, auto_filler_list (month_names_short
, 51, FALSE
));
1081 fillers
= g_list_prepend
1082 (fillers
, auto_filler_list (weekday_names_long
, 60, FALSE
));
1083 fillers
= g_list_prepend
1084 (fillers
, auto_filler_list (weekday_names_short
, 50, FALSE
));
1087 * Pass 2: Present all cells to the fillers and remove fillers that
1088 * cannot handle the contents.
1090 for (i
= j
= 0; j
< true_region_size
; j
++) {
1091 int ms
= merge_size
[j
];
1092 int col
= base_col
+ i
* col_inc
;
1093 int row
= base_row
+ i
* row_inc
;
1097 if (reverse
&& merges
[j
]) {
1098 col
-= range_width (merges
[j
]) - 1;
1099 row
-= range_height (merges
[j
]) - 1;
1101 cell
= sheet_cell_get (sheet
, col
, row
);
1104 AutoFiller
*af
= f
->data
;
1105 GList
*next
= f
->next
;
1107 af
->teach_cell (af
, cell
, j
);
1109 if (af
->status
== AFS_ERROR
) {
1110 fillers
= g_list_delete_link (fillers
, f
);
1120 /* Find the best filler that's ready. */
1121 for (f
= fillers
; f
; f
= f
->next
) {
1122 AutoFiller
*af1
= f
->data
;
1123 if (af1
->status
== AFS_READY
&&
1124 (af
== NULL
|| af1
->priority
> af
->priority
)) {
1130 /* Strange, but no fill. */
1132 while (i
< count_max
) {
1133 int k
= j
% true_region_size
;
1134 int ms
= merge_size
[k
];
1135 int col
= base_col
+ i
* col_inc
;
1136 int row
= base_row
+ i
* row_inc
;
1139 if (reverse
&& merges
[k
]) {
1140 col
-= range_width (merges
[k
]) - 1;
1141 row
-= range_height (merges
[k
]) - 1;
1143 cell
= sheet_cell_fetch (sheet
, col
, row
);
1144 af
->set_cell (af
, cell
, j
);
1146 sheet_style_set_pos (sheet
, col
, row
,
1147 gnm_style_dup (styles
[k
]));
1149 GnmRange r
= *merges
[k
];
1150 int ofs
= (i
/ region_size
) * region_size
;
1151 range_translate (&r
, sheet
,
1154 gnm_sheet_merge_add (sheet
, &r
, FALSE
, NULL
);
1161 int repeats
= (count_max
- 1) / region_size
;
1162 i
= repeats
* region_size
;
1164 while (i
< count_max
) {
1165 int ms
= merge_size
[j
];
1166 pos
.col
= base_col
+ i
* col_inc
;
1167 pos
.row
= base_row
+ i
* row_inc
;
1172 hint
= af
->hint (af
, &pos
, repeats
* true_region_size
+ j
- 1);
1176 AutoFiller
*af
= fillers
->data
;
1177 fillers
= g_list_delete_link (fillers
, fillers
);
1183 for (i
= 0; i
< true_region_size
; i
++)
1185 gnm_style_unref (styles
[i
]);
1190 g_free (merge_size
);
1196 add_item (GString
*dst
, char *item
, char const *sep
)
1200 g_string_append (dst
, sep
);
1202 g_string_append (dst
, item
);
1205 g_string_append (dst
, "?");
1209 sheet_autofill_internal (Sheet
*sheet
, gboolean singleton
,
1210 int base_col
, int base_row
,
1212 int end_col
, int end_row
,
1216 int right_col
= MAX (base_col
, end_col
);
1217 int bottom_row
= MAX (base_row
, end_row
);
1218 GString
*res
= NULL
;
1222 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
1225 res
= g_string_new (NULL
);
1230 if (base_col
> end_col
|| base_row
> end_row
) {
1231 if (base_col
!= end_col
+ w
- 1) {
1233 while (series
< h
) {
1235 sheet_autofill_dir (sheet
, singleton
,
1236 base_col
, base_row
- series
,
1237 w
, ABS (base_col
- (end_col
- 1)),
1239 right_col
, bottom_row
,
1243 pos
.row
= base_row
- series
;
1244 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1245 series
+= mr
? range_height (mr
) : 1;
1249 while (series
< w
) {
1251 sheet_autofill_dir (sheet
, singleton
,
1252 base_col
- series
, base_row
,
1253 h
, ABS (base_row
- (end_row
- 1)),
1255 right_col
, bottom_row
,
1259 pos
.col
= base_col
- series
;
1260 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1261 series
+= mr
? range_width (mr
) : 1;
1265 if (end_col
!= base_col
+ w
- 1) {
1267 while (series
< h
) {
1269 sheet_autofill_dir (sheet
, singleton
,
1270 base_col
, base_row
+ series
,
1271 w
, ABS (base_col
- (end_col
+ 1)),
1273 right_col
, bottom_row
,
1277 pos
.row
= base_row
+ series
;
1278 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1279 series
+= mr
? range_height (mr
) : 1;
1283 while (series
< w
) {
1285 sheet_autofill_dir (sheet
, singleton
,
1286 base_col
+ series
, base_row
,
1287 h
, ABS (base_row
- (end_row
+ 1)),
1289 right_col
, bottom_row
,
1292 pos
.col
= base_col
+ series
;
1293 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1294 series
+= mr
? range_width (mr
) : 1;
1305 * gnm_autofill_fill:
1307 * An internal routine to autofill a region. It does NOT
1308 * queue a recalc, flag a status update, or regen spans.
1311 gnm_autofill_fill (Sheet
*sheet
, gboolean singleton
,
1312 int base_col
, int base_row
,
1314 int end_col
, int end_row
)
1316 sheet_autofill_internal (sheet
, singleton
,
1324 gnm_autofill_hint (Sheet
*sheet
, gboolean default_increment
,
1325 int base_col
, int base_row
,
1327 int end_col
, int end_row
)
1329 return sheet_autofill_internal (sheet
, default_increment
,