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 (void)
46 char const *qtemplate
;
48 for (m
= 1; m
<= 12; m
++) {
49 month_names_long
[m
- 1] = go_date_month_name (m
, FALSE
);
50 month_names_short
[m
- 1] = go_date_month_name (m
, TRUE
);
52 for (wd
= 1; wd
<= 7; wd
++) {
53 weekday_names_long
[wd
- 1] = go_date_weekday_name (wd
, FALSE
);
54 weekday_names_short
[wd
- 1] = go_date_weekday_name (wd
, TRUE
);
57 /* xgettext: This is a C format string where %d will be replaced
58 by 1, 2, 3, or 4. A year will then be appended and we'll get
59 something like 3Q2005. If that makes no sense in your language,
60 translate to the empty string. */
62 has_quarters
= (qtemplate
[0] != 0);
65 for (q
= 1; q
<= 4; q
++)
66 quarters
[q
- 1] = g_strdup_printf (qtemplate
, q
);
71 gnm_autofill_shutdown (void)
77 for (m
= 1; m
<= 12; m
++) {
78 g_free (month_names_long
[m
- 1]);
79 g_free (month_names_short
[m
- 1]);
81 for (wd
= 1; wd
<= 7; wd
++) {
82 g_free (weekday_names_long
[wd
- 1]);
83 g_free (weekday_names_short
[wd
- 1]);
85 for (q
= 1; q
<= 4; q
++)
86 g_free (quarters
[q
- 1]);
89 /* ------------------------------------------------------------------------- */
97 typedef struct _AutoFiller AutoFiller
;
100 AutoFillerStatus status
;
103 void (*finalize
) (AutoFiller
*af
);
105 /* Given a new cell, adapt filler to that. */
106 void (*teach_cell
) (AutoFiller
*af
, const GnmCell
*cell
, int n
);
108 /* Set cell to the value of the nth sequence member. */
109 void (*set_cell
) (AutoFiller
*af
, GnmCell
*cell
, int n
);
111 /* Hint of what will be the nth element. */
112 char * (*hint
) (AutoFiller
*af
, GnmCellPos
*pos
, int n
);
116 af_finalize (AutoFiller
*af
)
121 /* ------------------------------------------------------------------------- */
123 * Arithmetic sequences:
127 * 1-Jan-2009, 2-Jan-2009, 3-Jan-2009, ...
128 * 1-Jan-2009, 8-Jan-2009, 15-Jan-2009, ...
129 * 00:00, 00:30, 01:00, ...
135 gboolean singleton
; /* Missing step becomes 1. */
136 gnm_float base
, step
;
138 GODateConventions
const *dateconv
;
139 } AutoFillerArithmetic
;
142 afa_finalize (AutoFiller
*af
)
144 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
145 go_format_unref (afa
->format
);
150 afa_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
152 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
153 GnmValue
*value
= cell
? cell
->value
: NULL
;
157 gnm_cell_has_expr (cell
) ||
158 !VALUE_IS_NUMBER (value
) ||
159 VALUE_IS_BOOLEAN (value
)) {
160 af
->status
= AFS_ERROR
;
164 f
= value_get_as_float (value
);
168 afa
->dateconv
= workbook_date_conv (cell
->base
.sheet
->workbook
);
170 if (afa
->singleton
) {
172 af
->status
= AFS_READY
;
174 if (VALUE_FMT (value
))
175 afa
->format
= go_format_ref (VALUE_FMT (value
));
178 afa
->step
= f
- afa
->base
;
179 af
->status
= AFS_READY
;
182 gnm_float step2
= (f
- afa
->base
) / n
;
183 gnm_float step_sum
= gnm_abs (afa
->step
) + gnm_abs (step2
);
184 gnm_float err
= step_sum
185 ? gnm_abs (afa
->step
- step2
) / step_sum
187 /* Be fairly lenient: */
188 if (err
> (n
+ 64) * GNM_EPSILON
) {
189 af
->status
= AFS_ERROR
;
197 afa_compute (AutoFillerArithmetic
*afa
, int n
)
199 gnm_float f
= afa
->base
+ n
* afa
->step
;
200 GnmValue
*v
= value_new_float (f
);
202 value_set_fmt (v
, afa
->format
);
207 afa_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
209 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
210 GnmValue
*v
= afa_compute (afa
, n
);
211 gnm_cell_set_value (cell
, v
);
215 afa_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
217 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
218 GnmValue
*v
= afa_compute (afa
, n
);
219 char *res
= format_value (NULL
, v
, -1, afa
->dateconv
);
225 auto_filler_arithmetic (gboolean singleton
)
227 AutoFillerArithmetic
*res
= g_new (AutoFillerArithmetic
, 1);
229 res
->filler
.status
= AFS_INCOMPLETE
;
230 res
->filler
.priority
= 100;
231 res
->filler
.finalize
= afa_finalize
;
232 res
->filler
.teach_cell
= afa_teach_cell
;
233 res
->filler
.set_cell
= afa_set_cell
;
234 res
->filler
.hint
= afa_hint
;
236 res
->dateconv
= NULL
;
237 res
->singleton
= singleton
;
242 /* ------------------------------------------------------------------------- */
245 gnm_float base
, step
;
246 GString
*prefix
, *suffix
;
247 gboolean fixed_length
;
248 int base_phase
, phases
;
254 as_finalize (ArithString
*as
)
257 g_string_free (as
->prefix
, TRUE
);
259 g_string_free (as
->suffix
, TRUE
);
264 as_check_prefix_suffix (ArithString
*as
, char const *s
, gsize slen
)
267 if (slen
< as
->prefix
->len
||
268 memcmp (s
, as
->prefix
->str
, as
->prefix
->len
) != 0)
270 s
+= as
->prefix
->len
;
271 slen
-= as
->prefix
->len
;
275 if (slen
< as
->suffix
->len
||
276 memcmp (s
+ slen
- as
->suffix
->len
,
278 as
->suffix
->len
) != 0)
286 as_compute_val (ArithString
*as
, int n
)
288 int pn
= (n
* as
->step
+ as
->base_phase
) / as
->phases
;
289 gnm_float f
= as
->base
+ pn
;
290 if (as
->fixed_length
)
291 f
= gnm_fmod (f
, as
->p10
);
296 as_compute (ArithString
*as
, int n
)
298 gnm_float f
= as_compute_val (as
, n
);
299 char const *prefix
= as
->prefix
? as
->prefix
->str
: "";
300 char const *suffix
= as
->suffix
? as
->suffix
->str
: "";
302 if (as
->fixed_length
) {
303 return g_strdup_printf ("%s%0*.0" GNM_FORMAT_f
"%s",
308 return g_strdup_printf ("%s%.0" GNM_FORMAT_f
"%s",
316 as_teach_first (ArithString
*as
, char const *s
)
321 for (pl
= 0; s
[pl
]; pl
++) {
322 if (g_ascii_isdigit (s
[pl
]))
324 if (!as
->fixed_length
&&
325 (s
[pl
] == '+' || s
[pl
] == '-') &&
326 g_ascii_isdigit (s
[pl
+ 1]))
334 g_string_append_len (as
->prefix
, s
, pl
);
336 return TRUE
; /* No prefix allowed. */
339 as
->base
= strtol (s
+ pl
, &end
, 10);
345 g_string_append (as
->suffix
, end
);
347 return TRUE
; /* No suffix allowed. */
350 as
->numlen
= end
- (s
+ pl
);
351 as
->p10
= gnm_pow10 (as
->numlen
);
357 as_teach_rest (ArithString
*as
, char const *s
, int n
, int phase
)
359 gsize slen
= strlen (s
);
362 char const *s2
= s
+ (as
->prefix
? as
->prefix
->len
: 0);
364 if (as_check_prefix_suffix (as
, s
, slen
))
367 if (g_ascii_isspace (*s2
))
371 if (as
->fixed_length
) {
372 if (!g_ascii_isdigit (*s2
))
374 val
= strtol (s2
, &end
, 10);
375 if (as
->numlen
!= (gsize
)(end
- s2
))
379 * Verify no leading zero so the fixed-length
380 * version gets a chance.
383 if (!g_ascii_isdigit (*s3
))
385 if (s3
[0] == '0' && g_ascii_isdigit (s3
[1]))
387 val
= strtol (s2
, &end
, 10);
390 if (errno
== ERANGE
|| end
!= s
+ slen
- (as
->suffix
? as
->suffix
->len
: 0))
394 as
->step
= (val
- as
->base
) * as
->phases
+ (phase
- as
->base_phase
);
395 if (as
->fixed_length
&& as
->step
< 0)
396 as
->step
+= as
->p10
* as
->phases
;
398 gnm_float f
= as_compute_val (as
, n
);
399 if (gnm_abs (f
- val
) > 0.5)
406 /* ------------------------------------------------------------------------- */
409 * Arithmetic sequences in strings:
411 * "Foo 1", "Foo 2", "Foo 3", ...
412 * "1 Bar", "3 Bar", "5 Bar", ...
413 * "Fall '99", "Fall '00", "Fall '01", ...
419 gboolean singleton
; /* Missing step becomes 1. */
421 } AutoFillerNumberString
;
424 afns_finalize (AutoFiller
*af
)
426 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
427 as_finalize (&afns
->as
);
432 afns_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
434 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
435 GnmValue
*value
= cell
? cell
->value
: NULL
;
439 gnm_cell_has_expr (cell
) ||
440 !VALUE_IS_STRING (value
)) {
442 af
->status
= AFS_ERROR
;
446 s
= value_peek_string (value
);
449 if (as_teach_first (&afns
->as
, s
))
453 af
->status
= AFS_READY
;
455 if (as_teach_rest (&afns
->as
, s
, n
, 0))
458 af
->status
= AFS_READY
;
463 afns_compute (AutoFillerNumberString
*afns
, int n
)
465 return as_compute (&afns
->as
, n
);
469 afns_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
471 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
472 char *s
= afns_compute (afns
, n
);
473 gnm_cell_set_value (cell
, value_new_string_nocopy (s
));
477 afns_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
479 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
480 return afns_compute (afns
, n
);
484 auto_filler_number_string (gboolean singleton
, gboolean fixed_length
)
486 AutoFillerNumberString
*res
= g_new (AutoFillerNumberString
, 1);
488 res
->filler
.status
= AFS_INCOMPLETE
;
489 res
->filler
.priority
= fixed_length
? 9 : 10;
490 res
->filler
.finalize
= afns_finalize
;
491 res
->filler
.teach_cell
= afns_teach_cell
;
492 res
->filler
.set_cell
= afns_set_cell
;
493 res
->filler
.hint
= afns_hint
;
494 res
->singleton
= singleton
;
495 res
->as
.fixed_length
= fixed_length
;
496 res
->as
.prefix
= g_string_new (NULL
);
497 res
->as
.suffix
= g_string_new (NULL
);
498 res
->as
.base_phase
= 0;
504 /* ------------------------------------------------------------------------- */
508 * 1-Jan-2009, 1-Feb-2009, 1-Mar-2009, ...
509 * 31-Jan-2009, 28-Feb-2009, 31-Mar-2009, ...
510 * 1-Jan-2009, 1-Jan-2010, 1-Jan-2011, ...
516 GODateConventions
const *dateconv
;
520 gboolean end_of_month
, same_of_month
;
524 afm_finalize (AutoFiller
*af
)
526 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
527 go_format_unref (afm
->format
);
532 afm_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
534 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
535 GnmValue
*value
= cell
? cell
->value
: NULL
;
539 if (value
== NULL
|| gnm_cell_has_expr (cell
)) {
541 af
->status
= AFS_ERROR
;
545 sf
= gnm_cell_get_format (cell
);
546 if (gnm_format_is_date_for_value (sf
, value
) != 1)
549 afm
->dateconv
= workbook_date_conv (cell
->base
.sheet
->workbook
);
550 if (!datetime_value_to_g (&d
, value
, afm
->dateconv
))
553 if (!g_date_is_last_of_month (&d
))
554 afm
->end_of_month
= FALSE
;
557 if (VALUE_FMT (value
))
558 afm
->format
= go_format_ref (VALUE_FMT (value
));
561 int year
= g_date_get_year (&d
);
562 int month
= g_date_get_month (&d
);
563 int day
= g_date_get_day (&d
);
566 if (day
!= g_date_get_day (&afm
->base
))
567 afm
->same_of_month
= FALSE
;
569 if (!afm
->same_of_month
&& !afm
->end_of_month
)
572 nmonths
= 12 * (year
- g_date_get_year (&afm
->base
)) +
573 (month
- g_date_get_month (&afm
->base
));
575 afm
->nmonths
= nmonths
;
576 else if (nmonths
!= afm
->nmonths
* n
)
579 af
->status
= AFS_READY
;
584 afm_compute (AutoFillerMonth
*afm
, int n
)
589 gnm_date_add_months (&d
, n
* afm
->nmonths
);
591 if (!g_date_valid (&d
) || g_date_get_year (&d
) > 9999)
594 if (afm
->end_of_month
) {
595 int year
= g_date_get_year (&d
);
596 int month
= g_date_get_month (&d
);
597 g_date_set_day (&d
, g_date_get_days_in_month (month
, year
));
600 v
= value_new_int (go_date_g_to_serial (&d
, afm
->dateconv
));
602 value_set_fmt (v
, afm
->format
);
607 afm_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
609 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
610 GnmValue
*v
= afm_compute (afm
, n
);
613 gnm_cell_set_value (cell
, v
);
616 eval_pos_init_cell (&ep
, cell
);
617 gnm_cell_set_value (cell
, value_new_error_VALUE (&ep
));
622 afm_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
624 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
625 GnmValue
*v
= afm_compute (afm
, n
);
629 res
= format_value (NULL
, v
, -1, afm
->dateconv
);
637 auto_filler_month (void)
639 AutoFillerMonth
*res
= g_new (AutoFillerMonth
, 1);
641 res
->filler
.status
= AFS_INCOMPLETE
;
642 res
->filler
.priority
= 200;
643 res
->filler
.finalize
= afm_finalize
;
644 res
->filler
.teach_cell
= afm_teach_cell
;
645 res
->filler
.set_cell
= afm_set_cell
;
646 res
->filler
.hint
= afm_hint
;
648 res
->dateconv
= NULL
;
649 res
->end_of_month
= TRUE
;
650 res
->same_of_month
= TRUE
;
655 /* ------------------------------------------------------------------------- */
661 gboolean with_number
;
666 afl_finalize (AutoFiller
*af
)
668 AutoFillerList
*afl
= (AutoFillerList
*)af
;
669 as_finalize (&afl
->as
);
674 afl_compute_phase (AutoFillerList
*afl
, int n
)
676 return (int)(n
* afl
->as
.step
+ afl
->as
.base_phase
) %
681 afl_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
683 AutoFillerList
*afl
= (AutoFillerList
*)af
;
684 GnmValue
*value
= cell
? cell
->value
: NULL
;
690 gnm_cell_has_expr (cell
) ||
691 !VALUE_IS_STRING (value
)) {
693 af
->status
= AFS_ERROR
;
697 s
= value_peek_string (value
);
698 for (ph
= 0; ph
< afl
->as
.phases
; ph
++) {
699 char const *e
= afl
->list
[ph
];
701 /* This isn't UTF-8 pretty. */
702 /* This isn't case pretty. */
703 /* This won't work if one list item is a prefix of another. */
704 if (strncmp (s
, e
, elen
) == 0)
707 if (ph
== afl
->as
.phases
)
711 afl
->as
.base_phase
= ph
;
713 if (afl
->with_number
) {
714 afl
->as
.prefix
= g_string_new (NULL
);
715 afl
->as
.suffix
= g_string_new (NULL
);
716 if (as_teach_first (&afl
->as
, s
+ elen
))
723 if (afl
->with_number
) {
724 if (as_teach_rest (&afl
->as
, s
+ elen
, n
, ph
))
731 int step
= ph
- afl
->as
.base_phase
;
735 step
+= afl
->as
.phases
;
738 if (ph
!= afl_compute_phase (afl
, n
))
743 af
->status
= AFS_READY
;
748 afl_compute (AutoFillerList
*afl
, int n
)
750 GString
*res
= g_string_new (afl
->list
[afl_compute_phase (afl
, n
)]);
752 if (afl
->with_number
) {
753 char *s
= as_compute (&afl
->as
, n
);
754 g_string_append (res
, s
);
758 return g_string_free (res
, FALSE
);
762 afl_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
764 AutoFillerList
*afl
= (AutoFillerList
*)af
;
765 char *str
= afl_compute (afl
, n
);
766 GnmValue
*val
= value_new_string_nocopy (str
);
767 gnm_cell_set_value (cell
, val
);
771 afl_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
773 AutoFillerList
*afl
= (AutoFillerList
*)af
;
774 return afl_compute (afl
, n
);
778 auto_filler_list (char **list
, int prio
, gboolean with_number
)
780 AutoFillerList
*res
= g_new (AutoFillerList
, 1);
782 res
->filler
.status
= AFS_INCOMPLETE
;
783 res
->filler
.priority
= prio
;
784 res
->filler
.finalize
= afl_finalize
;
785 res
->filler
.teach_cell
= afl_teach_cell
;
786 res
->filler
.set_cell
= afl_set_cell
;
787 res
->filler
.hint
= afl_hint
;
789 res
->with_number
= with_number
;
790 res
->as
.phases
= g_strv_length (list
);
791 res
->as
.fixed_length
= TRUE
;
792 res
->as
.prefix
= NULL
;
793 res
->as
.suffix
= NULL
;
798 /* ------------------------------------------------------------------------- */
805 const GnmCell
** cells
;
809 afc_finalize (AutoFiller
*af
)
811 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
817 afc_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
819 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
820 afe
->cells
[n
] = cell
;
821 if (n
== afe
->size
- 1) {
822 /* This actually includes the all-empty case. */
823 af
->status
= AFS_READY
;
828 afc_set_cell_hint (AutoFiller
*af
, GnmCell
*cell
, GnmCellPos
const *pos
,
829 int n
, gboolean doit
)
831 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
832 GnmCell
const *src
= afe
->cells
[n
% afe
->size
];
834 if (src
&& gnm_cell_has_expr (src
)) {
835 GnmExprRelocateInfo rinfo
;
836 GnmExprTop
const *texpr
;
837 GnmExprTop
const *src_texpr
= src
->base
.texpr
;
838 Sheet
*sheet
= src
->base
.sheet
;
840 /* Arrays are always assigned fully at the corner. */
841 if (gnm_expr_top_is_array_elem (src_texpr
, NULL
, NULL
))
844 rinfo
.reloc_type
= GNM_EXPR_RELOCATE_MOVE_RANGE
;
845 rinfo
.target_sheet
= rinfo
.origin_sheet
= NULL
;
846 rinfo
.col_offset
= rinfo
.row_offset
= 0;
847 rinfo
.origin
.start
= rinfo
.origin
.end
= *pos
;
848 parse_pos_init (&rinfo
.pos
, sheet
->workbook
, sheet
,
851 texpr
= gnm_expr_top_relocate (src_texpr
, &rinfo
, FALSE
);
853 /* Clip arrays that are only partially copied. */
854 if (gnm_expr_top_is_array_corner (src_texpr
)) {
855 GnmExpr
const *aexpr
;
856 int limit_x
= afe
->last
.col
- pos
->col
+ 1;
857 int limit_y
= afe
->last
.row
- pos
->row
+ 1;
860 gnm_expr_top_get_array_size (texpr
, &cols
, &rows
);
861 cols
= MIN (limit_x
, cols
);
862 rows
= MIN (limit_y
, rows
);
865 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (texpr
));
866 gnm_expr_top_unref (texpr
);
868 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr
));
871 gnm_cell_set_array_formula
873 pos
->col
, cell
->pos
.row
,
874 pos
->col
+ (cols
- 1),
875 pos
->row
+ (rows
- 1),
876 gnm_expr_top_new (aexpr
));
878 res
= gnm_expr_as_string (aexpr
,
881 gnm_expr_free (aexpr
);
885 gnm_cell_set_expr (cell
, texpr
);
887 res
= gnm_expr_top_as_string (texpr
,
890 gnm_expr_top_unref (texpr
);
893 gnm_cell_set_expr (cell
, src_texpr
);
895 res
= gnm_expr_top_as_string (src_texpr
,
901 gnm_cell_set_value (cell
, value_dup (src
->value
));
903 Sheet
const *sheet
= src
->base
.sheet
;
904 GODateConventions
const *dateconv
=
905 workbook_date_conv (sheet
->workbook
);
906 GOFormat
const *format
= gnm_cell_get_format (src
);
907 return format_value (format
, src
->value
, -1,
912 sheet_cell_remove (cell
->base
.sheet
, cell
, TRUE
, TRUE
);
914 res
= g_strdup (_("(empty)"));
921 afc_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
923 afc_set_cell_hint (af
, cell
, &cell
->pos
, n
, TRUE
);
927 afc_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
929 return afc_set_cell_hint (af
, NULL
, pos
, n
, FALSE
);
933 auto_filler_copy (int size
, guint last_col
, guint last_row
)
935 AutoFillerCopy
*res
= g_new (AutoFillerCopy
, 1);
937 res
->filler
.status
= AFS_INCOMPLETE
;
938 res
->filler
.priority
= 1;
939 res
->filler
.finalize
= afc_finalize
;
940 res
->filler
.teach_cell
= afc_teach_cell
;
941 res
->filler
.set_cell
= afc_set_cell
;
942 res
->filler
.hint
= afc_hint
;
944 res
->last
.col
= last_col
;
945 res
->last
.row
= last_row
;
946 res
->cells
= g_new0 (GnmCell
const *, size
);
951 /* ------------------------------------------------------------------------- */
954 calc_steps (const GnmRange
*r
, int col_inc
, int row_inc
)
958 ? range_width (r
) / ABS (col_inc
)
959 : range_height (r
) / ABS (row_inc
);
966 * (base_col,base_row): start of source area.
967 * (col_inc,row_inc): direction of fill.
968 * count_max: size of source+fill area in direction of fill.
969 * region_size: size of source area in direction of fill.
970 * (last_col,last_row): last cell of entire area being filled.
974 sheet_autofill_dir (Sheet
*sheet
, gboolean singleton
,
975 int base_col
, int base_row
,
978 int col_inc
, int row_inc
,
979 int last_col
, int last_row
,
982 GList
*fillers
= NULL
;
984 int i
, j
, true_region_size
;
985 AutoFiller
*af
= NULL
;
986 GnmStyle
const **styles
;
987 GnmRange
const **merges
;
992 if (count_max
<= 0 || region_size
<= 0)
996 * These are both indexed by cell number in the sequence we see
997 * cells. I.e., they go 0, 1, 2, ... no matter what way we fill
998 * and no matter if some cells are merged.
1000 * The allocations may be larger than we need, but we don't know
1001 * the right size yet.
1003 styles
= doit
? g_new0 (GnmStyle
const *, region_size
) : NULL
;
1004 merges
= g_new0 (GnmRange
const *, region_size
);
1007 * i counts rows/cols.
1008 * j follows, but skips hidden parts of merged cells.
1012 * Pass 1: Have a look at the merges. We always go right or down
1015 merge_size
= g_new0 (int, region_size
);
1016 reverse
= (col_inc
< 0 || row_inc
< 0);
1018 while (i
< region_size
) {
1019 int i2
= (reverse
? region_size
- 1 - i
: i
);
1020 int j2
= (reverse
? /*true_*/region_size
- 1 - j
: j
);
1021 int col2
= base_col
+ i2
* col_inc
;
1022 int row2
= base_row
+ i2
* row_inc
;
1027 styles
[j2
] = sheet_style_get (sheet
, col2
, row2
);
1028 gnm_style_ref (styles
[j2
]);
1033 merges
[j2
] = gnm_sheet_merge_contains_pos (sheet
, &pos
);
1034 di
= calc_steps (merges
[j2
], col_inc
, row_inc
);
1035 merge_size
[j2
] = di
- 1;
1039 true_region_size
= j
;
1041 /* We didn't know true_region_size up there. Patch up things. */
1043 memmove (merge_size
,
1044 merge_size
+ (region_size
- true_region_size
),
1045 true_region_size
* sizeof (*merge_size
));
1047 merges
+ (region_size
- true_region_size
),
1048 true_region_size
* sizeof (*merges
));
1051 styles
+ (region_size
- true_region_size
),
1052 true_region_size
* sizeof (*styles
));
1055 fillers
= g_list_prepend
1056 (fillers
, auto_filler_arithmetic (singleton
));
1057 fillers
= g_list_prepend
1058 (fillers
, auto_filler_number_string (singleton
, TRUE
));
1059 fillers
= g_list_prepend
1060 (fillers
, auto_filler_number_string (singleton
, FALSE
));
1061 fillers
= g_list_prepend
1062 (fillers
, auto_filler_month ());
1063 fillers
= g_list_prepend
1064 (fillers
, auto_filler_copy (true_region_size
,
1065 last_col
, last_row
));
1066 fillers
= g_list_prepend (fillers
, auto_filler_list (quarters
, 50, TRUE
));
1068 fillers
= g_list_prepend
1069 (fillers
, auto_filler_list (month_names_long
, 61, TRUE
));
1070 fillers
= g_list_prepend
1071 (fillers
, auto_filler_list (month_names_short
, 51, TRUE
));
1072 fillers
= g_list_prepend
1073 (fillers
, auto_filler_list (month_names_long
, 61, FALSE
));
1074 fillers
= g_list_prepend
1075 (fillers
, auto_filler_list (month_names_short
, 51, FALSE
));
1076 fillers
= g_list_prepend
1077 (fillers
, auto_filler_list (weekday_names_long
, 60, FALSE
));
1078 fillers
= g_list_prepend
1079 (fillers
, auto_filler_list (weekday_names_short
, 50, FALSE
));
1082 * Pass 2: Present all cells to the fillers and remove fillers that
1083 * cannot handle the contents.
1085 for (i
= j
= 0; j
< true_region_size
; j
++) {
1086 int ms
= merge_size
[j
];
1087 int col
= base_col
+ i
* col_inc
;
1088 int row
= base_row
+ i
* row_inc
;
1092 if (reverse
&& merges
[j
]) {
1093 col
-= range_width (merges
[j
]) - 1;
1094 row
-= range_height (merges
[j
]) - 1;
1096 cell
= sheet_cell_get (sheet
, col
, row
);
1099 AutoFiller
*af
= f
->data
;
1100 GList
*next
= f
->next
;
1102 af
->teach_cell (af
, cell
, j
);
1104 if (af
->status
== AFS_ERROR
) {
1105 fillers
= g_list_delete_link (fillers
, f
);
1115 /* Find the best filler that's ready. */
1116 for (f
= fillers
; f
; f
= f
->next
) {
1117 AutoFiller
*af1
= f
->data
;
1118 if (af1
->status
== AFS_READY
&&
1119 (af
== NULL
|| af1
->priority
> af
->priority
)) {
1125 /* Strange, but no fill. */
1127 while (i
< count_max
) {
1128 int k
= j
% true_region_size
;
1129 int ms
= merge_size
[k
];
1130 int col
= base_col
+ i
* col_inc
;
1131 int row
= base_row
+ i
* row_inc
;
1134 if (reverse
&& merges
[k
]) {
1135 col
-= range_width (merges
[k
]) - 1;
1136 row
-= range_height (merges
[k
]) - 1;
1138 cell
= sheet_cell_fetch (sheet
, col
, row
);
1139 af
->set_cell (af
, cell
, j
);
1141 sheet_style_set_pos (sheet
, col
, row
,
1142 gnm_style_dup (styles
[k
]));
1144 GnmRange r
= *merges
[k
];
1145 int ofs
= (i
/ region_size
) * region_size
;
1146 range_translate (&r
, sheet
,
1149 gnm_sheet_merge_add (sheet
, &r
, FALSE
, NULL
);
1156 int repeats
= (count_max
- 1) / region_size
;
1157 i
= repeats
* region_size
;
1159 while (i
< count_max
) {
1160 int ms
= merge_size
[j
];
1161 pos
.col
= base_col
+ i
* col_inc
;
1162 pos
.row
= base_row
+ i
* row_inc
;
1167 hint
= af
->hint (af
, &pos
, repeats
* true_region_size
+ j
- 1);
1171 AutoFiller
*af
= fillers
->data
;
1172 fillers
= g_list_delete_link (fillers
, fillers
);
1178 for (i
= 0; i
< true_region_size
; i
++)
1180 gnm_style_unref (styles
[i
]);
1185 g_free (merge_size
);
1191 add_item (GString
*dst
, char *item
, char const *sep
)
1195 g_string_append (dst
, sep
);
1197 g_string_append (dst
, item
);
1200 g_string_append (dst
, "?");
1204 sheet_autofill_internal (Sheet
*sheet
, gboolean singleton
,
1205 int base_col
, int base_row
,
1207 int end_col
, int end_row
,
1211 int right_col
= MAX (base_col
, end_col
);
1212 int bottom_row
= MAX (base_row
, end_row
);
1213 GString
*res
= NULL
;
1217 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
1220 res
= g_string_new (NULL
);
1225 if (base_col
> end_col
|| base_row
> end_row
) {
1226 if (base_col
!= end_col
+ w
- 1) {
1228 while (series
< h
) {
1230 sheet_autofill_dir (sheet
, singleton
,
1231 base_col
, base_row
- series
,
1232 w
, ABS (base_col
- (end_col
- 1)),
1234 right_col
, bottom_row
,
1238 pos
.row
= base_row
- series
;
1239 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1240 series
+= mr
? range_height (mr
) : 1;
1244 while (series
< w
) {
1246 sheet_autofill_dir (sheet
, singleton
,
1247 base_col
- series
, base_row
,
1248 h
, ABS (base_row
- (end_row
- 1)),
1250 right_col
, bottom_row
,
1254 pos
.col
= base_col
- series
;
1255 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1256 series
+= mr
? range_width (mr
) : 1;
1260 if (end_col
!= base_col
+ w
- 1) {
1262 while (series
< h
) {
1264 sheet_autofill_dir (sheet
, singleton
,
1265 base_col
, base_row
+ series
,
1266 w
, ABS (base_col
- (end_col
+ 1)),
1268 right_col
, bottom_row
,
1272 pos
.row
= base_row
+ series
;
1273 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1274 series
+= mr
? range_height (mr
) : 1;
1278 while (series
< w
) {
1280 sheet_autofill_dir (sheet
, singleton
,
1281 base_col
+ series
, base_row
,
1282 h
, ABS (base_row
- (end_row
+ 1)),
1284 right_col
, bottom_row
,
1287 pos
.col
= base_col
+ series
;
1288 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1289 series
+= mr
? range_width (mr
) : 1;
1300 * gnm_autofill_fill :
1302 * An internal routine to autofill a region. It does NOT
1303 * queue a recalc, flag a status update, or regen spans.
1306 gnm_autofill_fill (Sheet
*sheet
, gboolean singleton
,
1307 int base_col
, int base_row
,
1309 int end_col
, int end_row
)
1311 sheet_autofill_internal (sheet
, singleton
,
1319 gnm_autofill_hint (Sheet
*sheet
, gboolean default_increment
,
1320 int base_col
, int base_row
,
1322 int end_col
, int end_row
)
1324 return sheet_autofill_internal (sheet
, default_increment
,