Update Spanish translation
[gnumeric.git] / src / sheet-autofill.c
blob2e21b20680c35f2fe49cc9565b4e70a160ec8311
1 /*
2 * sheet-autofill.c: Provides the autofill features
4 * Author:
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)
8 */
9 #include <gnumeric-config.h>
10 #include <glib/gi18n-lib.h>
11 #include <gnumeric.h>
12 #include <sheet-autofill.h>
14 #include <sheet.h>
15 #include <cell.h>
16 #include <value.h>
17 #include <workbook.h>
18 #include <sheet-style.h>
19 #include <expr.h>
20 #include <gnm-datetime.h>
21 #include <mstyle.h>
22 #include <ranges.h>
23 #include <sheet-merge.h>
24 #include <gnm-format.h>
25 #include <goffice/goffice.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <stdlib.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;
40 /**
41 * gnm_autofill_init: (skip)
43 void
44 gnm_autofill_init (void)
46 GDateMonth m;
47 GDateWeekday wd;
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. */
63 qtemplate = _("%dQ");
64 has_quarters = (qtemplate[0] != 0);
65 if (has_quarters) {
66 int q;
67 for (q = 1; q <= 4; q++)
68 quarters[q - 1] = g_strdup_printf (qtemplate, q);
72 /**
73 * gnm_autofill_shutdown: (skip)
75 void
76 gnm_autofill_shutdown (void)
78 GDateMonth m;
79 GDateWeekday wd;
80 int q;
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 /* ------------------------------------------------------------------------- */
96 typedef enum {
97 AFS_INCOMPLETE,
98 AFS_READY,
99 AFS_ERROR
100 } AutoFillerStatus;
102 typedef struct _AutoFiller AutoFiller;
104 struct _AutoFiller {
105 AutoFillerStatus status;
106 int priority;
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);
120 static void
121 af_finalize (AutoFiller *af)
123 g_free (af);
126 /* ------------------------------------------------------------------------- */
128 * Arithmetic sequences:
130 * 1, 2, 3, ...
131 * 1, 3, 5, ....
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, ...
137 typedef struct {
138 AutoFiller filler;
140 gboolean singleton; /* Missing step becomes 1. */
141 gnm_float base, step;
142 GOFormat *format;
143 GODateConventions const *dateconv;
144 } AutoFillerArithmetic;
146 static void
147 afa_finalize (AutoFiller *af)
149 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
150 go_format_unref (afa->format);
151 af_finalize (af);
154 static void
155 afa_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
157 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
158 GnmValue *value = cell ? cell->value : NULL;
159 gnm_float f;
161 if (value == NULL ||
162 gnm_cell_has_expr (cell) ||
163 !VALUE_IS_NUMBER (value) ||
164 VALUE_IS_BOOLEAN (value)) {
165 af->status = AFS_ERROR;
166 return;
169 f = value_get_as_float (value);
171 switch (n) {
172 case 0:
173 afa->dateconv = sheet_date_conv (cell->base.sheet);
174 afa->base = f;
175 if (afa->singleton) {
176 afa->step = 1;
177 af->status = AFS_READY;
179 if (VALUE_FMT (value))
180 afa->format = go_format_ref (VALUE_FMT (value));
181 break;
182 case 1:
183 afa->step = f - afa->base;
184 af->status = AFS_READY;
185 break;
186 default: {
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
191 : 0;
192 /* Be fairly lenient: */
193 if (err > (n + 64) * GNM_EPSILON) {
194 af->status = AFS_ERROR;
195 return;
201 static GnmValue *
202 afa_compute (AutoFillerArithmetic *afa, int n)
204 gnm_float f = afa->base + n * afa->step;
205 GnmValue *v = value_new_float (f);
206 if (afa->format)
207 value_set_fmt (v, afa->format);
208 return v;
211 static void
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);
219 static char *
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);
225 value_release (v);
226 return res;
229 static AutoFiller *
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;
240 res->format = NULL;
241 res->dateconv = NULL;
242 res->singleton = singleton;
244 return &res->filler;
247 /* ------------------------------------------------------------------------- */
249 typedef struct {
250 gnm_float base, step;
251 GString *prefix, *suffix;
252 gboolean fixed_length;
253 int base_phase, phases;
254 gsize numlen;
255 gnm_float p10;
256 } ArithString;
258 static void
259 as_finalize (ArithString *as)
261 if (as->prefix)
262 g_string_free (as->prefix, TRUE);
263 if (as->suffix)
264 g_string_free (as->suffix, TRUE);
267 static gboolean
268 as_check_prefix_suffix (ArithString *as, char const *s, gsize slen)
270 if (as->prefix) {
271 if (slen < as->prefix->len ||
272 memcmp (s, as->prefix->str, as->prefix->len) != 0)
273 return TRUE;
274 s += as->prefix->len;
275 slen -= as->prefix->len;
278 if (as->suffix) {
279 if (slen < as->suffix->len ||
280 memcmp (s + slen - as->suffix->len,
281 as->suffix->str,
282 as->suffix->len) != 0)
283 return TRUE;
286 return FALSE;
289 static gnm_float
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);
296 return f;
299 static char *
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",
308 prefix,
309 (int)as->numlen, f,
310 suffix);
311 } else {
312 return g_strdup_printf ("%s%.0" GNM_FORMAT_f "%s",
313 prefix,
315 suffix);
319 static gboolean
320 as_teach_first (ArithString *as, char const *s)
322 gsize pl;
323 char *end;
325 for (pl = 0; s[pl]; pl++) {
326 if (g_ascii_isdigit (s[pl]))
327 break;
328 if (!as->fixed_length &&
329 (s[pl] == '+' || s[pl] == '-') &&
330 g_ascii_isdigit (s[pl + 1]))
331 break;
333 if (s[pl] == 0)
334 return TRUE;
336 if (pl > 0) {
337 if (as->prefix)
338 g_string_append_len (as->prefix, s, pl);
339 else
340 return TRUE; /* No prefix allowed. */
342 errno = 0;
343 as->base = strtol (s + pl, &end, 10);
344 as->step = 1;
345 if (errno)
346 return TRUE;
347 if (*end) {
348 if (as->suffix)
349 g_string_append (as->suffix, end);
350 else
351 return TRUE; /* No suffix allowed. */
354 as->numlen = end - (s + pl);
355 as->p10 = gnm_pow10 (as->numlen);
357 return FALSE;
360 static gboolean
361 as_teach_rest (ArithString *as, char const *s, int n, int phase)
363 gsize slen = strlen (s);
364 char *end;
365 gnm_float val;
366 char const *s2 = s + (as->prefix ? as->prefix->len : 0);
368 if (as_check_prefix_suffix (as, s, slen))
369 return TRUE;
371 if (g_ascii_isspace (*s2))
372 return TRUE;
374 errno = 0;
375 if (as->fixed_length) {
376 if (!g_ascii_isdigit (*s2))
377 return TRUE;
378 val = strtol (s2, &end, 10);
379 if (as->numlen != (gsize)(end - s2))
380 return TRUE;
381 } else {
383 * Verify no leading zero so the fixed-length
384 * version gets a chance.
386 char const *s3 = s2;
387 if (!g_ascii_isdigit (*s3))
388 s3++;
389 if (s3[0] == '0' && g_ascii_isdigit (s3[1]))
390 return TRUE;
391 val = strtol (s2, &end, 10);
394 if (errno == ERANGE || end != s + slen - (as->suffix ? as->suffix->len : 0))
395 return TRUE;
397 if (n == 1) {
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;
401 } else {
402 gnm_float f = as_compute_val (as, n);
403 if (gnm_abs (f - val) > 0.5)
404 return TRUE;
407 return FALSE;
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", ...
420 typedef struct {
421 AutoFiller filler;
423 gboolean singleton; /* Missing step becomes 1. */
424 ArithString as;
425 } AutoFillerNumberString;
427 static void
428 afns_finalize (AutoFiller *af)
430 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
431 as_finalize (&afns->as);
432 af_finalize (af);
435 static void
436 afns_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
438 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
439 GnmValue *value = cell ? cell->value : NULL;
440 char const *s;
442 if (value == NULL ||
443 gnm_cell_has_expr (cell) ||
444 !VALUE_IS_STRING (value)) {
445 bad:
446 af->status = AFS_ERROR;
447 return;
450 s = value_peek_string (value);
452 if (n == 0) {
453 if (as_teach_first (&afns->as, s))
454 goto bad;
456 if (afns->singleton)
457 af->status = AFS_READY;
458 } else {
459 if (as_teach_rest (&afns->as, s, n, 0))
460 goto bad;
462 af->status = AFS_READY;
466 static char *
467 afns_compute (AutoFillerNumberString *afns, int n)
469 return as_compute (&afns->as, n);
472 static void
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));
480 static char *
481 afns_hint (AutoFiller *af, GnmCellPos *pos, int n)
483 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
484 return afns_compute (afns, n);
487 static AutoFiller *
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;
503 res->as.phases = 1;
505 return &res->filler;
508 /* ------------------------------------------------------------------------- */
510 * Month sequences:
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, ...
517 typedef struct {
518 AutoFiller filler;
520 GODateConventions const *dateconv;
521 GDate base;
522 GOFormat *format;
523 int nmonths;
524 gboolean end_of_month, same_of_month;
525 } AutoFillerMonth;
527 static void
528 afm_finalize (AutoFiller *af)
530 AutoFillerMonth *afm = (AutoFillerMonth *)af;
531 go_format_unref (afm->format);
532 af_finalize (af);
535 static void
536 afm_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
538 AutoFillerMonth *afm = (AutoFillerMonth *)af;
539 GnmValue *value = cell ? cell->value : NULL;
540 GDate d;
541 const GOFormat *sf;
543 if (value == NULL || gnm_cell_has_expr (cell)) {
544 bad:
545 af->status = AFS_ERROR;
546 return;
549 sf = gnm_cell_get_format (cell);
550 if (gnm_format_is_date_for_value (sf, value) != 1)
551 goto bad;
553 afm->dateconv = sheet_date_conv (cell->base.sheet);
554 if (!datetime_value_to_g (&d, value, afm->dateconv))
555 goto bad;
557 if (!g_date_is_last_of_month (&d))
558 afm->end_of_month = FALSE;
560 if (n == 0) {
561 if (VALUE_FMT (value))
562 afm->format = go_format_ref (VALUE_FMT (value));
563 afm->base = d;
564 } else {
565 int year = g_date_get_year (&d);
566 int month = g_date_get_month (&d);
567 int day = g_date_get_day (&d);
568 int nmonths;
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)
574 goto bad;
576 nmonths = 12 * (year - g_date_get_year (&afm->base)) +
577 (month - g_date_get_month (&afm->base));
578 if (n == 1)
579 afm->nmonths = nmonths;
580 else if (nmonths != afm->nmonths * n)
581 goto bad;
583 af->status = AFS_READY;
587 static GnmValue *
588 afm_compute (AutoFillerMonth *afm, int n)
590 GDate d = afm->base;
591 GnmValue *v;
593 gnm_date_add_months (&d, n * afm->nmonths);
595 if (!g_date_valid (&d) || g_date_get_year (&d) > 9999)
596 return NULL;
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));
605 if (afm->format)
606 value_set_fmt (v, afm->format);
607 return v;
610 static void
611 afm_set_cell (AutoFiller *af, GnmCell *cell, int n)
613 AutoFillerMonth *afm = (AutoFillerMonth *)af;
614 GnmValue *v = afm_compute (afm, n);
616 if (v)
617 gnm_cell_set_value (cell, v);
618 else {
619 GnmEvalPos ep;
620 eval_pos_init_cell (&ep, cell);
621 gnm_cell_set_value (cell, value_new_error_VALUE (&ep));
625 static char *
626 afm_hint (AutoFiller *af, GnmCellPos *pos, int n)
628 AutoFillerMonth *afm = (AutoFillerMonth *)af;
629 GnmValue *v = afm_compute (afm, n);
630 char *res = NULL;
632 if (v) {
633 res = format_value (NULL, v, -1, afm->dateconv);
634 value_release (v);
637 return res;
640 static AutoFiller *
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;
651 res->format = NULL;
652 res->dateconv = NULL;
653 res->end_of_month = TRUE;
654 res->same_of_month = TRUE;
656 return &res->filler;
659 /* ------------------------------------------------------------------------- */
661 typedef struct {
662 AutoFiller filler;
664 char **list;
665 gboolean with_number;
666 ArithString as;
667 } AutoFillerList;
669 static void
670 afl_finalize (AutoFiller *af)
672 AutoFillerList *afl = (AutoFillerList *)af;
673 as_finalize (&afl->as);
674 af_finalize (af);
677 static int
678 afl_compute_phase (AutoFillerList *afl, int n)
680 return (int)(n * afl->as.step + afl->as.base_phase) %
681 afl->as.phases;
684 static void
685 afl_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
687 AutoFillerList *afl = (AutoFillerList *)af;
688 GnmValue *value = cell ? cell->value : NULL;
689 char const *s;
690 gsize elen = 0;
691 int ph;
693 if (value == NULL ||
694 gnm_cell_has_expr (cell) ||
695 !VALUE_IS_STRING (value)) {
696 bad:
697 af->status = AFS_ERROR;
698 return;
701 s = value_peek_string (value);
702 for (ph = 0; ph < afl->as.phases; ph++) {
703 char const *e = afl->list[ph];
704 elen = strlen (e);
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)
709 break;
711 if (ph == afl->as.phases)
712 goto bad;
714 if (n == 0) {
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))
721 goto bad;
722 } else {
723 if (s[elen] != 0)
724 goto bad;
726 } else {
727 if (afl->with_number) {
728 if (as_teach_rest (&afl->as, s + elen, n, ph))
729 goto bad;
730 } else {
731 if (s[elen] != 0)
732 goto bad;
734 if (n == 1) {
735 int step = ph - afl->as.base_phase;
736 if (step == 0)
737 goto bad;
738 if (step < 0)
739 step += afl->as.phases;
740 afl->as.step = step;
741 } else {
742 if (ph != afl_compute_phase (afl, n))
743 goto bad;
747 af->status = AFS_READY;
751 static char *
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);
759 g_free (s);
762 return g_string_free (res, FALSE);
765 static void
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);
774 static char *
775 afl_hint (AutoFiller *af, GnmCellPos *pos, int n)
777 AutoFillerList *afl = (AutoFillerList *)af;
778 return afl_compute (afl, n);
781 static AutoFiller *
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;
792 res->list = list;
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;
799 return &res->filler;
802 /* ------------------------------------------------------------------------- */
804 typedef struct {
805 AutoFiller filler;
807 int size;
808 GnmCellPos last;
809 const GnmCell ** cells;
810 } AutoFillerCopy;
812 static void
813 afc_finalize (AutoFiller *af)
815 AutoFillerCopy *afe = (AutoFillerCopy *)af;
816 g_free (afe->cells);
817 af_finalize (af);
820 static void
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;
831 static char *
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];
837 char *res = NULL;
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))
846 return 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,
853 pos->col, pos->row);
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;
862 int cols, rows;
864 gnm_expr_top_get_array_size (texpr, &cols, &rows);
865 cols = MIN (limit_x, cols);
866 rows = MIN (limit_y, rows);
868 if (texpr) {
869 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (texpr));
870 gnm_expr_top_unref (texpr);
871 } else
872 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr));
874 if (doit)
875 gnm_cell_set_array_formula
876 (cell->base.sheet,
877 pos->col, cell->pos.row,
878 pos->col + (cols - 1),
879 pos->row + (rows - 1),
880 gnm_expr_top_new (aexpr));
881 else {
882 res = gnm_expr_as_string (aexpr,
883 &rinfo.pos,
884 sheet->convs);
885 gnm_expr_free (aexpr);
887 } else if (texpr) {
888 if (doit)
889 gnm_cell_set_expr (cell, texpr);
890 else
891 res = gnm_expr_top_as_string (texpr,
892 &rinfo.pos,
893 sheet->convs);
894 gnm_expr_top_unref (texpr);
895 } else {
896 if (doit)
897 gnm_cell_set_expr (cell, src_texpr);
898 else
899 res = gnm_expr_top_as_string (src_texpr,
900 &rinfo.pos,
901 sheet->convs);
903 } else if (src) {
904 if (doit)
905 gnm_cell_set_value (cell, value_dup (src->value));
906 else {
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,
912 dateconv);
914 } else {
915 if (doit)
916 sheet_cell_remove (cell->base.sheet, cell, TRUE, TRUE);
917 else
918 res = g_strdup (_("(empty)"));
921 return res;
924 static void
925 afc_set_cell (AutoFiller *af, GnmCell *cell, int n)
927 afc_set_cell_hint (af, cell, &cell->pos, n, TRUE);
930 static char *
931 afc_hint (AutoFiller *af, GnmCellPos *pos, int n)
933 return afc_set_cell_hint (af, NULL, pos, n, FALSE);
936 static AutoFiller *
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;
947 res->size = size;
948 res->last.col = last_col;
949 res->last.row = last_row;
950 res->cells = g_new0 (GnmCell const *, size);
952 return &res->filler;
955 /* ------------------------------------------------------------------------- */
957 static int
958 calc_steps (const GnmRange *r, int col_inc, int row_inc)
960 if (r)
961 return col_inc
962 ? range_width (r) / ABS (col_inc)
963 : range_height (r) / ABS (row_inc);
964 else
965 return 1;
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.
977 static char *
978 sheet_autofill_dir (Sheet *sheet, gboolean singleton,
979 int base_col, int base_row,
980 int region_size,
981 int count_max,
982 int col_inc, int row_inc,
983 int last_col, int last_row,
984 gboolean doit)
986 GList *fillers = NULL;
987 GList *f;
988 int i, j, true_region_size;
989 AutoFiller *af = NULL;
990 GnmStyle const **styles;
991 GnmRange const **merges;
992 int *merge_size;
993 char *hint = NULL;
994 gboolean reverse;
996 if (count_max <= 0 || region_size <= 0)
997 return NULL;
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
1017 * in this pass.
1019 merge_size = g_new0 (int, region_size);
1020 reverse = (col_inc < 0 || row_inc < 0);
1021 i = j = 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;
1027 GnmCellPos pos;
1028 int di;
1030 if (styles) {
1031 styles[j2] = sheet_style_get (sheet, col2, row2);
1032 gnm_style_ref (styles[j2]);
1035 pos.col = col2;
1036 pos.row = row2;
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;
1040 i += di;
1041 j++;
1043 true_region_size = j;
1045 /* We didn't know true_region_size up there. Patch up things. */
1046 if (reverse) {
1047 memmove (merge_size,
1048 merge_size + (region_size - true_region_size),
1049 true_region_size * sizeof (*merge_size));
1050 memmove (merges,
1051 merges + (region_size - true_region_size),
1052 true_region_size * sizeof (*merges));
1053 if (styles)
1054 memmove (styles,
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;
1093 GnmCell *cell;
1094 GList *f = fillers;
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);
1102 while (f) {
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);
1110 af->finalize (af);
1113 f = next;
1116 i += (ms + 1);
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)) {
1124 af = af1;
1128 if (!af) {
1129 /* Strange, but no fill. */
1130 } else if (doit) {
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;
1136 GnmCell *cell;
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]));
1147 if (merges[k]) {
1148 GnmRange r = *merges[k];
1149 int ofs = (i / region_size) * region_size;
1150 range_translate (&r, sheet,
1151 ofs * col_inc,
1152 ofs * row_inc);
1153 gnm_sheet_merge_add (sheet, &r, FALSE, NULL);
1155 i += (ms + 1);
1156 j++;
1158 } else {
1159 GnmCellPos pos;
1160 int repeats = (count_max - 1) / region_size;
1161 i = repeats * region_size;
1162 j = 0;
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;
1167 i += (ms + 1);
1168 j++;
1171 hint = af->hint (af, &pos, repeats * true_region_size + j - 1);
1174 while (fillers) {
1175 AutoFiller *af = fillers->data;
1176 fillers = g_list_delete_link (fillers, fillers);
1177 af->finalize (af);
1180 if (styles) {
1181 int i;
1182 for (i = 0; i < true_region_size; i++)
1183 if (styles[i])
1184 gnm_style_unref (styles[i]);
1185 g_free (styles);
1188 g_free (merges);
1189 g_free (merge_size);
1191 return hint;
1194 static void
1195 add_item (GString *dst, char *item, char const *sep)
1197 if (!dst) return;
1198 if (dst->len)
1199 g_string_append (dst, sep);
1200 if (item) {
1201 g_string_append (dst, item);
1202 g_free (item);
1203 } else
1204 g_string_append (dst, "?");
1207 static GString *
1208 sheet_autofill_internal (Sheet *sheet, gboolean singleton,
1209 int base_col, int base_row,
1210 int w, int h,
1211 int end_col, int end_row,
1212 gboolean doit)
1214 int series = 0;
1215 int right_col = MAX (base_col, end_col);
1216 int bottom_row = MAX (base_row, end_row);
1217 GString *res = NULL;
1218 GnmCellPos pos;
1219 GnmRange const *mr;
1221 g_return_val_if_fail (IS_SHEET (sheet), NULL);
1223 if (!doit)
1224 res = g_string_new (NULL);
1226 pos.col = base_col;
1227 pos.row = base_row;
1229 if (base_col > end_col || base_row > end_row) {
1230 if (base_col != end_col + w - 1) {
1231 /* LEFT */
1232 while (series < h) {
1233 add_item (res,
1234 sheet_autofill_dir (sheet, singleton,
1235 base_col, base_row - series,
1236 w, ABS (base_col - (end_col - 1)),
1237 -1, 0,
1238 right_col, bottom_row,
1239 doit),
1240 "\n");
1242 pos.row = base_row - series;
1243 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1244 series += mr ? range_height (mr) : 1;
1246 } else {
1247 /* UP */
1248 while (series < w) {
1249 add_item (res,
1250 sheet_autofill_dir (sheet, singleton,
1251 base_col - series, base_row,
1252 h, ABS (base_row - (end_row - 1)),
1253 0, -1,
1254 right_col, bottom_row,
1255 doit),
1256 " | ");
1258 pos.col = base_col - series;
1259 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1260 series += mr ? range_width (mr) : 1;
1263 } else {
1264 if (end_col != base_col + w - 1) {
1265 /* RIGHT */
1266 while (series < h) {
1267 add_item (res,
1268 sheet_autofill_dir (sheet, singleton,
1269 base_col, base_row + series,
1270 w, ABS (base_col - (end_col + 1)),
1271 1, 0,
1272 right_col, bottom_row,
1273 doit),
1274 "\n");
1276 pos.row = base_row + series;
1277 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1278 series += mr ? range_height (mr) : 1;
1280 } else {
1281 /* DOWN */
1282 while (series < w) {
1283 add_item (res,
1284 sheet_autofill_dir (sheet, singleton,
1285 base_col + series, base_row,
1286 h, ABS (base_row - (end_row + 1)),
1287 0, 1,
1288 right_col, bottom_row,
1289 doit),
1290 " | ");
1291 pos.col = base_col + series;
1292 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1293 series += mr ? range_width (mr) : 1;
1298 return res;
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.
1309 void
1310 gnm_autofill_fill (Sheet *sheet, gboolean singleton,
1311 int base_col, int base_row,
1312 int w, int h,
1313 int end_col, int end_row)
1315 sheet_autofill_internal (sheet, singleton,
1316 base_col, base_row,
1317 w, h,
1318 end_col, end_row,
1319 TRUE);
1322 GString *
1323 gnm_autofill_hint (Sheet *sheet, gboolean default_increment,
1324 int base_col, int base_row,
1325 int w, int h,
1326 int end_col, int end_row)
1328 return sheet_autofill_internal (sheet, default_increment,
1329 base_col, base_row,
1330 w, h,
1331 end_col, end_row,
1332 FALSE);