2 * sheet-autofill.c: Provides the autofill features
5 * Miguel de Icaza (miguel@kernel.org), 1998
6 * Jody Goldberg (jody@gnome.org), 1999-2006
7 * Copyright (C) 1999-2009 Morten Welinder (terra@gnome.org)
9 #include <gnumeric-config.h>
10 #include <glib/gi18n-lib.h>
12 #include <sheet-autofill.h>
18 #include <sheet-style.h>
20 #include <gnm-datetime.h>
23 #include <sheet-merge.h>
24 #include <gnm-format.h>
25 #include <goffice/goffice.h>
31 /* ------------------------------------------------------------------------- */
33 static char *month_names_long
[12 + 1];
34 static char *month_names_short
[12 + 1];
35 static char *weekday_names_long
[7 + 1];
36 static char *weekday_names_short
[7 + 1];
37 static char *quarters
[4 + 1];
38 static gboolean has_quarters
;
41 * gnm_autofill_init: (skip)
44 gnm_autofill_init (void)
48 char const *qtemplate
;
50 for (m
= 1; m
<= 12; m
++) {
51 month_names_long
[m
- 1] = go_date_month_name (m
, FALSE
);
52 month_names_short
[m
- 1] = go_date_month_name (m
, TRUE
);
54 for (wd
= 1; wd
<= 7; wd
++) {
55 weekday_names_long
[wd
- 1] = go_date_weekday_name (wd
, FALSE
);
56 weekday_names_short
[wd
- 1] = go_date_weekday_name (wd
, TRUE
);
59 /* xgettext: This is a C format string where %d will be replaced
60 by 1, 2, 3, or 4. A year will then be appended and we'll get
61 something like 3Q2005. If that makes no sense in your language,
62 translate to the empty string. */
64 has_quarters
= (qtemplate
[0] != 0);
67 for (q
= 1; q
<= 4; q
++)
68 quarters
[q
- 1] = g_strdup_printf (qtemplate
, q
);
73 * gnm_autofill_shutdown: (skip)
76 gnm_autofill_shutdown (void)
82 for (m
= 1; m
<= 12; m
++) {
83 g_free (month_names_long
[m
- 1]);
84 g_free (month_names_short
[m
- 1]);
86 for (wd
= 1; wd
<= 7; wd
++) {
87 g_free (weekday_names_long
[wd
- 1]);
88 g_free (weekday_names_short
[wd
- 1]);
90 for (q
= 1; q
<= 4; q
++)
91 g_free (quarters
[q
- 1]);
94 /* ------------------------------------------------------------------------- */
102 typedef struct _AutoFiller AutoFiller
;
105 AutoFillerStatus status
;
108 void (*finalize
) (AutoFiller
*af
);
110 /* Given a new cell, adapt filler to that. */
111 void (*teach_cell
) (AutoFiller
*af
, const GnmCell
*cell
, int n
);
113 /* Set cell to the value of the nth sequence member. */
114 void (*set_cell
) (AutoFiller
*af
, GnmCell
*cell
, int n
);
116 /* Hint of what will be the nth element. */
117 char * (*hint
) (AutoFiller
*af
, GnmCellPos
*pos
, int n
);
121 af_finalize (AutoFiller
*af
)
126 /* ------------------------------------------------------------------------- */
128 * Arithmetic sequences:
132 * 1-Jan-2009, 2-Jan-2009, 3-Jan-2009, ...
133 * 1-Jan-2009, 8-Jan-2009, 15-Jan-2009, ...
134 * 00:00, 00:30, 01:00, ...
140 gboolean singleton
; /* Missing step becomes 1. */
141 gnm_float base
, step
;
143 GODateConventions
const *dateconv
;
144 } AutoFillerArithmetic
;
147 afa_finalize (AutoFiller
*af
)
149 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
150 go_format_unref (afa
->format
);
155 afa_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
157 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
158 GnmValue
*value
= cell
? cell
->value
: NULL
;
162 gnm_cell_has_expr (cell
) ||
163 !VALUE_IS_NUMBER (value
) ||
164 VALUE_IS_BOOLEAN (value
)) {
165 af
->status
= AFS_ERROR
;
169 f
= value_get_as_float (value
);
173 afa
->dateconv
= sheet_date_conv (cell
->base
.sheet
);
175 if (afa
->singleton
) {
177 af
->status
= AFS_READY
;
179 if (VALUE_FMT (value
))
180 afa
->format
= go_format_ref (VALUE_FMT (value
));
183 afa
->step
= f
- afa
->base
;
184 af
->status
= AFS_READY
;
187 gnm_float step2
= (f
- afa
->base
) / n
;
188 gnm_float step_sum
= gnm_abs (afa
->step
) + gnm_abs (step2
);
189 gnm_float err
= step_sum
190 ? gnm_abs (afa
->step
- step2
) / step_sum
192 /* Be fairly lenient: */
193 if (err
> (n
+ 64) * GNM_EPSILON
) {
194 af
->status
= AFS_ERROR
;
202 afa_compute (AutoFillerArithmetic
*afa
, int n
)
204 gnm_float f
= afa
->base
+ n
* afa
->step
;
205 GnmValue
*v
= value_new_float (f
);
207 value_set_fmt (v
, afa
->format
);
212 afa_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
214 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
215 GnmValue
*v
= afa_compute (afa
, n
);
216 gnm_cell_set_value (cell
, v
);
220 afa_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
222 AutoFillerArithmetic
*afa
= (AutoFillerArithmetic
*)af
;
223 GnmValue
*v
= afa_compute (afa
, n
);
224 char *res
= format_value (NULL
, v
, -1, afa
->dateconv
);
230 auto_filler_arithmetic (gboolean singleton
)
232 AutoFillerArithmetic
*res
= g_new (AutoFillerArithmetic
, 1);
234 res
->filler
.status
= AFS_INCOMPLETE
;
235 res
->filler
.priority
= 100;
236 res
->filler
.finalize
= afa_finalize
;
237 res
->filler
.teach_cell
= afa_teach_cell
;
238 res
->filler
.set_cell
= afa_set_cell
;
239 res
->filler
.hint
= afa_hint
;
241 res
->dateconv
= NULL
;
242 res
->singleton
= singleton
;
247 /* ------------------------------------------------------------------------- */
250 gnm_float base
, step
;
251 GString
*prefix
, *suffix
;
252 gboolean fixed_length
;
253 int base_phase
, phases
;
259 as_finalize (ArithString
*as
)
262 g_string_free (as
->prefix
, TRUE
);
264 g_string_free (as
->suffix
, TRUE
);
268 as_check_prefix_suffix (ArithString
*as
, char const *s
, gsize slen
)
271 if (slen
< as
->prefix
->len
||
272 memcmp (s
, as
->prefix
->str
, as
->prefix
->len
) != 0)
274 s
+= as
->prefix
->len
;
275 slen
-= as
->prefix
->len
;
279 if (slen
< as
->suffix
->len
||
280 memcmp (s
+ slen
- as
->suffix
->len
,
282 as
->suffix
->len
) != 0)
290 as_compute_val (ArithString
*as
, int n
)
292 int pn
= (n
* as
->step
+ as
->base_phase
) / as
->phases
;
293 gnm_float f
= as
->base
+ pn
;
294 if (as
->fixed_length
)
295 f
= gnm_fmod (f
, as
->p10
);
300 as_compute (ArithString
*as
, int n
)
302 gnm_float f
= as_compute_val (as
, n
);
303 char const *prefix
= as
->prefix
? as
->prefix
->str
: "";
304 char const *suffix
= as
->suffix
? as
->suffix
->str
: "";
306 if (as
->fixed_length
) {
307 return g_strdup_printf ("%s%0*.0" GNM_FORMAT_f
"%s",
312 return g_strdup_printf ("%s%.0" GNM_FORMAT_f
"%s",
320 as_teach_first (ArithString
*as
, char const *s
)
325 for (pl
= 0; s
[pl
]; pl
++) {
326 if (g_ascii_isdigit (s
[pl
]))
328 if (!as
->fixed_length
&&
329 (s
[pl
] == '+' || s
[pl
] == '-') &&
330 g_ascii_isdigit (s
[pl
+ 1]))
338 g_string_append_len (as
->prefix
, s
, pl
);
340 return TRUE
; /* No prefix allowed. */
343 as
->base
= strtol (s
+ pl
, &end
, 10);
349 g_string_append (as
->suffix
, end
);
351 return TRUE
; /* No suffix allowed. */
354 as
->numlen
= end
- (s
+ pl
);
355 as
->p10
= gnm_pow10 (as
->numlen
);
361 as_teach_rest (ArithString
*as
, char const *s
, int n
, int phase
)
363 gsize slen
= strlen (s
);
366 char const *s2
= s
+ (as
->prefix
? as
->prefix
->len
: 0);
368 if (as_check_prefix_suffix (as
, s
, slen
))
371 if (g_ascii_isspace (*s2
))
375 if (as
->fixed_length
) {
376 if (!g_ascii_isdigit (*s2
))
378 val
= strtol (s2
, &end
, 10);
379 if (as
->numlen
!= (gsize
)(end
- s2
))
383 * Verify no leading zero so the fixed-length
384 * version gets a chance.
387 if (!g_ascii_isdigit (*s3
))
389 if (s3
[0] == '0' && g_ascii_isdigit (s3
[1]))
391 val
= strtol (s2
, &end
, 10);
394 if (errno
== ERANGE
|| end
!= s
+ slen
- (as
->suffix
? as
->suffix
->len
: 0))
398 as
->step
= (val
- as
->base
) * as
->phases
+ (phase
- as
->base_phase
);
399 if (as
->fixed_length
&& as
->step
< 0)
400 as
->step
+= as
->p10
* as
->phases
;
402 gnm_float f
= as_compute_val (as
, n
);
403 if (gnm_abs (f
- val
) > 0.5)
410 /* ------------------------------------------------------------------------- */
413 * Arithmetic sequences in strings:
415 * "Foo 1", "Foo 2", "Foo 3", ...
416 * "1 Bar", "3 Bar", "5 Bar", ...
417 * "Fall '99", "Fall '00", "Fall '01", ...
423 gboolean singleton
; /* Missing step becomes 1. */
425 } AutoFillerNumberString
;
428 afns_finalize (AutoFiller
*af
)
430 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
431 as_finalize (&afns
->as
);
436 afns_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
438 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
439 GnmValue
*value
= cell
? cell
->value
: NULL
;
443 gnm_cell_has_expr (cell
) ||
444 !VALUE_IS_STRING (value
)) {
446 af
->status
= AFS_ERROR
;
450 s
= value_peek_string (value
);
453 if (as_teach_first (&afns
->as
, s
))
457 af
->status
= AFS_READY
;
459 if (as_teach_rest (&afns
->as
, s
, n
, 0))
462 af
->status
= AFS_READY
;
467 afns_compute (AutoFillerNumberString
*afns
, int n
)
469 return as_compute (&afns
->as
, n
);
473 afns_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
475 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
476 char *s
= afns_compute (afns
, n
);
477 gnm_cell_set_value (cell
, value_new_string_nocopy (s
));
481 afns_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
483 AutoFillerNumberString
*afns
= (AutoFillerNumberString
*)af
;
484 return afns_compute (afns
, n
);
488 auto_filler_number_string (gboolean singleton
, gboolean fixed_length
)
490 AutoFillerNumberString
*res
= g_new (AutoFillerNumberString
, 1);
492 res
->filler
.status
= AFS_INCOMPLETE
;
493 res
->filler
.priority
= fixed_length
? 9 : 10;
494 res
->filler
.finalize
= afns_finalize
;
495 res
->filler
.teach_cell
= afns_teach_cell
;
496 res
->filler
.set_cell
= afns_set_cell
;
497 res
->filler
.hint
= afns_hint
;
498 res
->singleton
= singleton
;
499 res
->as
.fixed_length
= fixed_length
;
500 res
->as
.prefix
= g_string_new (NULL
);
501 res
->as
.suffix
= g_string_new (NULL
);
502 res
->as
.base_phase
= 0;
508 /* ------------------------------------------------------------------------- */
512 * 1-Jan-2009, 1-Feb-2009, 1-Mar-2009, ...
513 * 31-Jan-2009, 28-Feb-2009, 31-Mar-2009, ...
514 * 1-Jan-2009, 1-Jan-2010, 1-Jan-2011, ...
520 GODateConventions
const *dateconv
;
524 gboolean end_of_month
, same_of_month
;
528 afm_finalize (AutoFiller
*af
)
530 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
531 go_format_unref (afm
->format
);
536 afm_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
538 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
539 GnmValue
*value
= cell
? cell
->value
: NULL
;
543 if (value
== NULL
|| gnm_cell_has_expr (cell
)) {
545 af
->status
= AFS_ERROR
;
549 sf
= gnm_cell_get_format (cell
);
550 if (gnm_format_is_date_for_value (sf
, value
) != 1)
553 afm
->dateconv
= sheet_date_conv (cell
->base
.sheet
);
554 if (!datetime_value_to_g (&d
, value
, afm
->dateconv
))
557 if (!g_date_is_last_of_month (&d
))
558 afm
->end_of_month
= FALSE
;
561 if (VALUE_FMT (value
))
562 afm
->format
= go_format_ref (VALUE_FMT (value
));
565 int year
= g_date_get_year (&d
);
566 int month
= g_date_get_month (&d
);
567 int day
= g_date_get_day (&d
);
570 if (day
!= g_date_get_day (&afm
->base
))
571 afm
->same_of_month
= FALSE
;
573 if (!afm
->same_of_month
&& !afm
->end_of_month
)
576 nmonths
= 12 * (year
- g_date_get_year (&afm
->base
)) +
577 (month
- g_date_get_month (&afm
->base
));
579 afm
->nmonths
= nmonths
;
580 else if (nmonths
!= afm
->nmonths
* n
)
583 af
->status
= AFS_READY
;
588 afm_compute (AutoFillerMonth
*afm
, int n
)
593 gnm_date_add_months (&d
, n
* afm
->nmonths
);
595 if (!g_date_valid (&d
) || g_date_get_year (&d
) > 9999)
598 if (afm
->end_of_month
) {
599 int year
= g_date_get_year (&d
);
600 int month
= g_date_get_month (&d
);
601 g_date_set_day (&d
, g_date_get_days_in_month (month
, year
));
604 v
= value_new_int (go_date_g_to_serial (&d
, afm
->dateconv
));
606 value_set_fmt (v
, afm
->format
);
611 afm_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
613 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
614 GnmValue
*v
= afm_compute (afm
, n
);
617 gnm_cell_set_value (cell
, v
);
620 eval_pos_init_cell (&ep
, cell
);
621 gnm_cell_set_value (cell
, value_new_error_VALUE (&ep
));
626 afm_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
628 AutoFillerMonth
*afm
= (AutoFillerMonth
*)af
;
629 GnmValue
*v
= afm_compute (afm
, n
);
633 res
= format_value (NULL
, v
, -1, afm
->dateconv
);
641 auto_filler_month (void)
643 AutoFillerMonth
*res
= g_new (AutoFillerMonth
, 1);
645 res
->filler
.status
= AFS_INCOMPLETE
;
646 res
->filler
.priority
= 200;
647 res
->filler
.finalize
= afm_finalize
;
648 res
->filler
.teach_cell
= afm_teach_cell
;
649 res
->filler
.set_cell
= afm_set_cell
;
650 res
->filler
.hint
= afm_hint
;
652 res
->dateconv
= NULL
;
653 res
->end_of_month
= TRUE
;
654 res
->same_of_month
= TRUE
;
659 /* ------------------------------------------------------------------------- */
665 gboolean with_number
;
670 afl_finalize (AutoFiller
*af
)
672 AutoFillerList
*afl
= (AutoFillerList
*)af
;
673 as_finalize (&afl
->as
);
678 afl_compute_phase (AutoFillerList
*afl
, int n
)
680 return (int)(n
* afl
->as
.step
+ afl
->as
.base_phase
) %
685 afl_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
687 AutoFillerList
*afl
= (AutoFillerList
*)af
;
688 GnmValue
*value
= cell
? cell
->value
: NULL
;
694 gnm_cell_has_expr (cell
) ||
695 !VALUE_IS_STRING (value
)) {
697 af
->status
= AFS_ERROR
;
701 s
= value_peek_string (value
);
702 for (ph
= 0; ph
< afl
->as
.phases
; ph
++) {
703 char const *e
= afl
->list
[ph
];
705 /* This isn't UTF-8 pretty. */
706 /* This isn't case pretty. */
707 /* This won't work if one list item is a prefix of another. */
708 if (strncmp (s
, e
, elen
) == 0)
711 if (ph
== afl
->as
.phases
)
715 afl
->as
.base_phase
= ph
;
717 if (afl
->with_number
) {
718 afl
->as
.prefix
= g_string_new (NULL
);
719 afl
->as
.suffix
= g_string_new (NULL
);
720 if (as_teach_first (&afl
->as
, s
+ elen
))
727 if (afl
->with_number
) {
728 if (as_teach_rest (&afl
->as
, s
+ elen
, n
, ph
))
735 int step
= ph
- afl
->as
.base_phase
;
739 step
+= afl
->as
.phases
;
742 if (ph
!= afl_compute_phase (afl
, n
))
747 af
->status
= AFS_READY
;
752 afl_compute (AutoFillerList
*afl
, int n
)
754 GString
*res
= g_string_new (afl
->list
[afl_compute_phase (afl
, n
)]);
756 if (afl
->with_number
) {
757 char *s
= as_compute (&afl
->as
, n
);
758 g_string_append (res
, s
);
762 return g_string_free (res
, FALSE
);
766 afl_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
768 AutoFillerList
*afl
= (AutoFillerList
*)af
;
769 char *str
= afl_compute (afl
, n
);
770 GnmValue
*val
= value_new_string_nocopy (str
);
771 gnm_cell_set_value (cell
, val
);
775 afl_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
777 AutoFillerList
*afl
= (AutoFillerList
*)af
;
778 return afl_compute (afl
, n
);
782 auto_filler_list (char **list
, int prio
, gboolean with_number
)
784 AutoFillerList
*res
= g_new (AutoFillerList
, 1);
786 res
->filler
.status
= AFS_INCOMPLETE
;
787 res
->filler
.priority
= prio
;
788 res
->filler
.finalize
= afl_finalize
;
789 res
->filler
.teach_cell
= afl_teach_cell
;
790 res
->filler
.set_cell
= afl_set_cell
;
791 res
->filler
.hint
= afl_hint
;
793 res
->with_number
= with_number
;
794 res
->as
.phases
= g_strv_length (list
);
795 res
->as
.fixed_length
= TRUE
;
796 res
->as
.prefix
= NULL
;
797 res
->as
.suffix
= NULL
;
802 /* ------------------------------------------------------------------------- */
809 const GnmCell
** cells
;
813 afc_finalize (AutoFiller
*af
)
815 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
821 afc_teach_cell (AutoFiller
*af
, const GnmCell
*cell
, int n
)
823 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
824 afe
->cells
[n
] = cell
;
825 if (n
== afe
->size
- 1) {
826 /* This actually includes the all-empty case. */
827 af
->status
= AFS_READY
;
832 afc_set_cell_hint (AutoFiller
*af
, GnmCell
*cell
, GnmCellPos
const *pos
,
833 int n
, gboolean doit
)
835 AutoFillerCopy
*afe
= (AutoFillerCopy
*)af
;
836 GnmCell
const *src
= afe
->cells
[n
% afe
->size
];
838 if (src
&& gnm_cell_has_expr (src
)) {
839 GnmExprRelocateInfo rinfo
;
840 GnmExprTop
const *texpr
;
841 GnmExprTop
const *src_texpr
= src
->base
.texpr
;
842 Sheet
*sheet
= src
->base
.sheet
;
844 /* Arrays are always assigned fully at the corner. */
845 if (gnm_expr_top_is_array_elem (src_texpr
, NULL
, NULL
))
848 rinfo
.reloc_type
= GNM_EXPR_RELOCATE_MOVE_RANGE
;
849 rinfo
.target_sheet
= rinfo
.origin_sheet
= NULL
;
850 rinfo
.col_offset
= rinfo
.row_offset
= 0;
851 rinfo
.origin
.start
= rinfo
.origin
.end
= *pos
;
852 parse_pos_init (&rinfo
.pos
, sheet
->workbook
, sheet
,
855 texpr
= gnm_expr_top_relocate (src_texpr
, &rinfo
, FALSE
);
857 /* Clip arrays that are only partially copied. */
858 if (gnm_expr_top_is_array_corner (src_texpr
)) {
859 GnmExpr
const *aexpr
;
860 int limit_x
= afe
->last
.col
- pos
->col
+ 1;
861 int limit_y
= afe
->last
.row
- pos
->row
+ 1;
864 gnm_expr_top_get_array_size (texpr
, &cols
, &rows
);
865 cols
= MIN (limit_x
, cols
);
866 rows
= MIN (limit_y
, rows
);
869 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (texpr
));
870 gnm_expr_top_unref (texpr
);
872 aexpr
= gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr
));
875 gnm_cell_set_array_formula
877 pos
->col
, cell
->pos
.row
,
878 pos
->col
+ (cols
- 1),
879 pos
->row
+ (rows
- 1),
880 gnm_expr_top_new (aexpr
));
882 res
= gnm_expr_as_string (aexpr
,
885 gnm_expr_free (aexpr
);
889 gnm_cell_set_expr (cell
, texpr
);
891 res
= gnm_expr_top_as_string (texpr
,
894 gnm_expr_top_unref (texpr
);
897 gnm_cell_set_expr (cell
, src_texpr
);
899 res
= gnm_expr_top_as_string (src_texpr
,
905 gnm_cell_set_value (cell
, value_dup (src
->value
));
907 Sheet
const *sheet
= src
->base
.sheet
;
908 GODateConventions
const *dateconv
=
909 sheet_date_conv (sheet
);
910 GOFormat
const *format
= gnm_cell_get_format (src
);
911 return format_value (format
, src
->value
, -1,
916 sheet_cell_remove (cell
->base
.sheet
, cell
, TRUE
, TRUE
);
918 res
= g_strdup (_("(empty)"));
925 afc_set_cell (AutoFiller
*af
, GnmCell
*cell
, int n
)
927 afc_set_cell_hint (af
, cell
, &cell
->pos
, n
, TRUE
);
931 afc_hint (AutoFiller
*af
, GnmCellPos
*pos
, int n
)
933 return afc_set_cell_hint (af
, NULL
, pos
, n
, FALSE
);
937 auto_filler_copy (int size
, guint last_col
, guint last_row
)
939 AutoFillerCopy
*res
= g_new (AutoFillerCopy
, 1);
941 res
->filler
.status
= AFS_INCOMPLETE
;
942 res
->filler
.priority
= 1;
943 res
->filler
.finalize
= afc_finalize
;
944 res
->filler
.teach_cell
= afc_teach_cell
;
945 res
->filler
.set_cell
= afc_set_cell
;
946 res
->filler
.hint
= afc_hint
;
948 res
->last
.col
= last_col
;
949 res
->last
.row
= last_row
;
950 res
->cells
= g_new0 (GnmCell
const *, size
);
955 /* ------------------------------------------------------------------------- */
958 calc_steps (const GnmRange
*r
, int col_inc
, int row_inc
)
962 ? range_width (r
) / ABS (col_inc
)
963 : range_height (r
) / ABS (row_inc
);
970 * (base_col,base_row): start of source area.
971 * (col_inc,row_inc): direction of fill.
972 * count_max: size of source+fill area in direction of fill.
973 * region_size: size of source area in direction of fill.
974 * (last_col,last_row): last cell of entire area being filled.
978 sheet_autofill_dir (Sheet
*sheet
, gboolean singleton
,
979 int base_col
, int base_row
,
982 int col_inc
, int row_inc
,
983 int last_col
, int last_row
,
986 GList
*fillers
= NULL
;
988 int i
, j
, true_region_size
;
989 AutoFiller
*af
= NULL
;
990 GnmStyle
const **styles
;
991 GnmRange
const **merges
;
996 if (count_max
<= 0 || region_size
<= 0)
1000 * These are both indexed by cell number in the sequence we see
1001 * cells. I.e., they go 0, 1, 2, ... no matter what way we fill
1002 * and no matter if some cells are merged.
1004 * The allocations may be larger than we need, but we don't know
1005 * the right size yet.
1007 styles
= doit
? g_new0 (GnmStyle
const *, region_size
) : NULL
;
1008 merges
= g_new0 (GnmRange
const *, region_size
);
1011 * i counts rows/cols.
1012 * j follows, but skips hidden parts of merged cells.
1016 * Pass 1: Have a look at the merges. We always go right or down
1019 merge_size
= g_new0 (int, region_size
);
1020 reverse
= (col_inc
< 0 || row_inc
< 0);
1022 while (i
< region_size
) {
1023 int i2
= (reverse
? region_size
- 1 - i
: i
);
1024 int j2
= (reverse
? /*true_*/region_size
- 1 - j
: j
);
1025 int col2
= base_col
+ i2
* col_inc
;
1026 int row2
= base_row
+ i2
* row_inc
;
1031 styles
[j2
] = sheet_style_get (sheet
, col2
, row2
);
1032 gnm_style_ref (styles
[j2
]);
1037 merges
[j2
] = gnm_sheet_merge_contains_pos (sheet
, &pos
);
1038 di
= calc_steps (merges
[j2
], col_inc
, row_inc
);
1039 merge_size
[j2
] = di
- 1;
1043 true_region_size
= j
;
1045 /* We didn't know true_region_size up there. Patch up things. */
1047 memmove (merge_size
,
1048 merge_size
+ (region_size
- true_region_size
),
1049 true_region_size
* sizeof (*merge_size
));
1051 merges
+ (region_size
- true_region_size
),
1052 true_region_size
* sizeof (*merges
));
1055 styles
+ (region_size
- true_region_size
),
1056 true_region_size
* sizeof (*styles
));
1059 fillers
= g_list_prepend
1060 (fillers
, auto_filler_arithmetic (singleton
));
1061 fillers
= g_list_prepend
1062 (fillers
, auto_filler_number_string (singleton
, TRUE
));
1063 fillers
= g_list_prepend
1064 (fillers
, auto_filler_number_string (singleton
, FALSE
));
1065 fillers
= g_list_prepend
1066 (fillers
, auto_filler_month ());
1067 fillers
= g_list_prepend
1068 (fillers
, auto_filler_copy (true_region_size
,
1069 last_col
, last_row
));
1070 fillers
= g_list_prepend (fillers
, auto_filler_list (quarters
, 50, TRUE
));
1072 fillers
= g_list_prepend
1073 (fillers
, auto_filler_list (month_names_long
, 61, TRUE
));
1074 fillers
= g_list_prepend
1075 (fillers
, auto_filler_list (month_names_short
, 51, TRUE
));
1076 fillers
= g_list_prepend
1077 (fillers
, auto_filler_list (month_names_long
, 61, FALSE
));
1078 fillers
= g_list_prepend
1079 (fillers
, auto_filler_list (month_names_short
, 51, FALSE
));
1080 fillers
= g_list_prepend
1081 (fillers
, auto_filler_list (weekday_names_long
, 60, FALSE
));
1082 fillers
= g_list_prepend
1083 (fillers
, auto_filler_list (weekday_names_short
, 50, FALSE
));
1086 * Pass 2: Present all cells to the fillers and remove fillers that
1087 * cannot handle the contents.
1089 for (i
= j
= 0; j
< true_region_size
; j
++) {
1090 int ms
= merge_size
[j
];
1091 int col
= base_col
+ i
* col_inc
;
1092 int row
= base_row
+ i
* row_inc
;
1096 if (reverse
&& merges
[j
]) {
1097 col
-= range_width (merges
[j
]) - 1;
1098 row
-= range_height (merges
[j
]) - 1;
1100 cell
= sheet_cell_get (sheet
, col
, row
);
1103 AutoFiller
*af
= f
->data
;
1104 GList
*next
= f
->next
;
1106 af
->teach_cell (af
, cell
, j
);
1108 if (af
->status
== AFS_ERROR
) {
1109 fillers
= g_list_delete_link (fillers
, f
);
1119 /* Find the best filler that's ready. */
1120 for (f
= fillers
; f
; f
= f
->next
) {
1121 AutoFiller
*af1
= f
->data
;
1122 if (af1
->status
== AFS_READY
&&
1123 (af
== NULL
|| af1
->priority
> af
->priority
)) {
1129 /* Strange, but no fill. */
1131 while (i
< count_max
) {
1132 int k
= j
% true_region_size
;
1133 int ms
= merge_size
[k
];
1134 int col
= base_col
+ i
* col_inc
;
1135 int row
= base_row
+ i
* row_inc
;
1138 if (reverse
&& merges
[k
]) {
1139 col
-= range_width (merges
[k
]) - 1;
1140 row
-= range_height (merges
[k
]) - 1;
1142 cell
= sheet_cell_fetch (sheet
, col
, row
);
1143 af
->set_cell (af
, cell
, j
);
1145 sheet_style_set_pos (sheet
, col
, row
,
1146 gnm_style_dup (styles
[k
]));
1148 GnmRange r
= *merges
[k
];
1149 int ofs
= (i
/ region_size
) * region_size
;
1150 range_translate (&r
, sheet
,
1153 gnm_sheet_merge_add (sheet
, &r
, FALSE
, NULL
);
1160 int repeats
= (count_max
- 1) / region_size
;
1161 i
= repeats
* region_size
;
1163 while (i
< count_max
) {
1164 int ms
= merge_size
[j
];
1165 pos
.col
= base_col
+ i
* col_inc
;
1166 pos
.row
= base_row
+ i
* row_inc
;
1171 hint
= af
->hint (af
, &pos
, repeats
* true_region_size
+ j
- 1);
1175 AutoFiller
*af
= fillers
->data
;
1176 fillers
= g_list_delete_link (fillers
, fillers
);
1182 for (i
= 0; i
< true_region_size
; i
++)
1184 gnm_style_unref (styles
[i
]);
1189 g_free (merge_size
);
1195 add_item (GString
*dst
, char *item
, char const *sep
)
1199 g_string_append (dst
, sep
);
1201 g_string_append (dst
, item
);
1204 g_string_append (dst
, "?");
1208 sheet_autofill_internal (Sheet
*sheet
, gboolean singleton
,
1209 int base_col
, int base_row
,
1211 int end_col
, int end_row
,
1215 int right_col
= MAX (base_col
, end_col
);
1216 int bottom_row
= MAX (base_row
, end_row
);
1217 GString
*res
= NULL
;
1221 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
1224 res
= g_string_new (NULL
);
1229 if (base_col
> end_col
|| base_row
> end_row
) {
1230 if (base_col
!= end_col
+ w
- 1) {
1232 while (series
< h
) {
1234 sheet_autofill_dir (sheet
, singleton
,
1235 base_col
, base_row
- series
,
1236 w
, ABS (base_col
- (end_col
- 1)),
1238 right_col
, bottom_row
,
1242 pos
.row
= base_row
- series
;
1243 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1244 series
+= mr
? range_height (mr
) : 1;
1248 while (series
< w
) {
1250 sheet_autofill_dir (sheet
, singleton
,
1251 base_col
- series
, base_row
,
1252 h
, ABS (base_row
- (end_row
- 1)),
1254 right_col
, bottom_row
,
1258 pos
.col
= base_col
- series
;
1259 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1260 series
+= mr
? range_width (mr
) : 1;
1264 if (end_col
!= base_col
+ w
- 1) {
1266 while (series
< h
) {
1268 sheet_autofill_dir (sheet
, singleton
,
1269 base_col
, base_row
+ series
,
1270 w
, ABS (base_col
- (end_col
+ 1)),
1272 right_col
, bottom_row
,
1276 pos
.row
= base_row
+ series
;
1277 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1278 series
+= mr
? range_height (mr
) : 1;
1282 while (series
< w
) {
1284 sheet_autofill_dir (sheet
, singleton
,
1285 base_col
+ series
, base_row
,
1286 h
, ABS (base_row
- (end_row
+ 1)),
1288 right_col
, bottom_row
,
1291 pos
.col
= base_col
+ series
;
1292 mr
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
1293 series
+= mr
? range_width (mr
) : 1;
1304 * gnm_autofill_fill:
1306 * An internal routine to autofill a region. It does NOT
1307 * queue a recalc, flag a status update, or regen spans.
1310 gnm_autofill_fill (Sheet
*sheet
, gboolean singleton
,
1311 int base_col
, int base_row
,
1313 int end_col
, int end_row
)
1315 sheet_autofill_internal (sheet
, singleton
,
1323 gnm_autofill_hint (Sheet
*sheet
, gboolean default_increment
,
1324 int base_col
, int base_row
,
1326 int end_col
, int end_row
)
1328 return sheet_autofill_internal (sheet
, default_increment
,