Introspection update
[gnumeric.git] / src / sheet-autofill.c
blobbc52432fb567816801ec4c5bc03c5eb0d6ce9fe7
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * sheet-autofill.c: Provides the autofill features
5 * Author:
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)
9 */
10 #include <gnumeric-config.h>
11 #include <glib/gi18n-lib.h>
12 #include "gnumeric.h"
13 #include "sheet-autofill.h"
15 #include "sheet.h"
16 #include "cell.h"
17 #include "value.h"
18 #include "workbook.h"
19 #include "sheet-style.h"
20 #include "expr.h"
21 #include "gnm-datetime.h"
22 #include "mstyle.h"
23 #include "ranges.h"
24 #include "sheet-merge.h"
25 #include "gnm-format.h"
26 #include <goffice/goffice.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <stdlib.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;
41 void
42 gnm_autofill_init (void)
44 GDateMonth m;
45 GDateWeekday wd;
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. */
61 qtemplate = _("%dQ");
62 has_quarters = (qtemplate[0] != 0);
63 if (has_quarters) {
64 int q;
65 for (q = 1; q <= 4; q++)
66 quarters[q - 1] = g_strdup_printf (qtemplate, q);
70 void
71 gnm_autofill_shutdown (void)
73 GDateMonth m;
74 GDateWeekday wd;
75 int q;
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 /* ------------------------------------------------------------------------- */
91 typedef enum {
92 AFS_INCOMPLETE,
93 AFS_READY,
94 AFS_ERROR
95 } AutoFillerStatus;
97 typedef struct _AutoFiller AutoFiller;
99 struct _AutoFiller {
100 AutoFillerStatus status;
101 int priority;
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);
115 static void
116 af_finalize (AutoFiller *af)
118 g_free (af);
121 /* ------------------------------------------------------------------------- */
123 * Arithmetic sequences:
125 * 1, 2, 3, ...
126 * 1, 3, 5, ....
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, ...
132 typedef struct {
133 AutoFiller filler;
135 gboolean singleton; /* Missing step becomes 1. */
136 gnm_float base, step;
137 GOFormat *format;
138 GODateConventions const *dateconv;
139 } AutoFillerArithmetic;
141 static void
142 afa_finalize (AutoFiller *af)
144 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
145 go_format_unref (afa->format);
146 af_finalize (af);
149 static void
150 afa_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
152 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
153 GnmValue *value = cell ? cell->value : NULL;
154 gnm_float f;
156 if (value == NULL ||
157 gnm_cell_has_expr (cell) ||
158 !VALUE_IS_NUMBER (value) ||
159 VALUE_IS_BOOLEAN (value)) {
160 af->status = AFS_ERROR;
161 return;
164 f = value_get_as_float (value);
166 switch (n) {
167 case 0:
168 afa->dateconv = workbook_date_conv (cell->base.sheet->workbook);
169 afa->base = f;
170 if (afa->singleton) {
171 afa->step = 1;
172 af->status = AFS_READY;
174 if (VALUE_FMT (value))
175 afa->format = go_format_ref (VALUE_FMT (value));
176 break;
177 case 1:
178 afa->step = f - afa->base;
179 af->status = AFS_READY;
180 break;
181 default: {
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
186 : 0;
187 /* Be fairly lenient: */
188 if (err > (n + 64) * GNM_EPSILON) {
189 af->status = AFS_ERROR;
190 return;
196 static GnmValue *
197 afa_compute (AutoFillerArithmetic *afa, int n)
199 gnm_float f = afa->base + n * afa->step;
200 GnmValue *v = value_new_float (f);
201 if (afa->format)
202 value_set_fmt (v, afa->format);
203 return v;
206 static void
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);
214 static char *
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);
220 value_release (v);
221 return res;
224 static AutoFiller *
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;
235 res->format = NULL;
236 res->dateconv = NULL;
237 res->singleton = singleton;
239 return &res->filler;
242 /* ------------------------------------------------------------------------- */
244 typedef struct {
245 gnm_float base, step;
246 GString *prefix, *suffix;
247 gboolean fixed_length;
248 int base_phase, phases;
249 gsize numlen;
250 gnm_float p10;
251 } ArithString;
253 static void
254 as_finalize (ArithString *as)
256 if (as->prefix)
257 g_string_free (as->prefix, TRUE);
258 if (as->suffix)
259 g_string_free (as->suffix, TRUE);
262 static
263 gboolean
264 as_check_prefix_suffix (ArithString *as, char const *s, gsize slen)
266 if (as->prefix) {
267 if (slen < as->prefix->len ||
268 memcmp (s, as->prefix->str, as->prefix->len) != 0)
269 return TRUE;
270 s += as->prefix->len;
271 slen -= as->prefix->len;
274 if (as->suffix) {
275 if (slen < as->suffix->len ||
276 memcmp (s + slen - as->suffix->len,
277 as->suffix->str,
278 as->suffix->len) != 0)
279 return TRUE;
282 return FALSE;
285 static gnm_float
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);
292 return f;
295 static char *
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",
304 prefix,
305 (int)as->numlen, f,
306 suffix);
307 } else {
308 return g_strdup_printf ("%s%.0" GNM_FORMAT_f "%s",
309 prefix,
311 suffix);
315 static gboolean
316 as_teach_first (ArithString *as, char const *s)
318 gsize pl;
319 char *end;
321 for (pl = 0; s[pl]; pl++) {
322 if (g_ascii_isdigit (s[pl]))
323 break;
324 if (!as->fixed_length &&
325 (s[pl] == '+' || s[pl] == '-') &&
326 g_ascii_isdigit (s[pl + 1]))
327 break;
329 if (s[pl] == 0)
330 return TRUE;
332 if (pl > 0) {
333 if (as->prefix)
334 g_string_append_len (as->prefix, s, pl);
335 else
336 return TRUE; /* No prefix allowed. */
338 errno = 0;
339 as->base = strtol (s + pl, &end, 10);
340 as->step = 1;
341 if (errno)
342 return TRUE;
343 if (*end) {
344 if (as->suffix)
345 g_string_append (as->suffix, end);
346 else
347 return TRUE; /* No suffix allowed. */
350 as->numlen = end - (s + pl);
351 as->p10 = gnm_pow10 (as->numlen);
353 return FALSE;
356 static gboolean
357 as_teach_rest (ArithString *as, char const *s, int n, int phase)
359 gsize slen = strlen (s);
360 char *end;
361 gnm_float val;
362 char const *s2 = s + (as->prefix ? as->prefix->len : 0);
364 if (as_check_prefix_suffix (as, s, slen))
365 return TRUE;
367 if (g_ascii_isspace (*s2))
368 return TRUE;
370 errno = 0;
371 if (as->fixed_length) {
372 if (!g_ascii_isdigit (*s2))
373 return TRUE;
374 val = strtol (s2, &end, 10);
375 if (as->numlen != (gsize)(end - s2))
376 return TRUE;
377 } else {
379 * Verify no leading zero so the fixed-length
380 * version gets a chance.
382 char const *s3 = s2;
383 if (!g_ascii_isdigit (*s3))
384 s3++;
385 if (s3[0] == '0' && g_ascii_isdigit (s3[1]))
386 return TRUE;
387 val = strtol (s2, &end, 10);
390 if (errno == ERANGE || end != s + slen - (as->suffix ? as->suffix->len : 0))
391 return TRUE;
393 if (n == 1) {
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;
397 } else {
398 gnm_float f = as_compute_val (as, n);
399 if (gnm_abs (f - val) > 0.5)
400 return TRUE;
403 return FALSE;
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", ...
416 typedef struct {
417 AutoFiller filler;
419 gboolean singleton; /* Missing step becomes 1. */
420 ArithString as;
421 } AutoFillerNumberString;
423 static void
424 afns_finalize (AutoFiller *af)
426 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
427 as_finalize (&afns->as);
428 af_finalize (af);
431 static void
432 afns_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
434 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
435 GnmValue *value = cell ? cell->value : NULL;
436 char const *s;
438 if (value == NULL ||
439 gnm_cell_has_expr (cell) ||
440 !VALUE_IS_STRING (value)) {
441 bad:
442 af->status = AFS_ERROR;
443 return;
446 s = value_peek_string (value);
448 if (n == 0) {
449 if (as_teach_first (&afns->as, s))
450 goto bad;
452 if (afns->singleton)
453 af->status = AFS_READY;
454 } else {
455 if (as_teach_rest (&afns->as, s, n, 0))
456 goto bad;
458 af->status = AFS_READY;
462 static char *
463 afns_compute (AutoFillerNumberString *afns, int n)
465 return as_compute (&afns->as, n);
468 static void
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));
476 static char *
477 afns_hint (AutoFiller *af, GnmCellPos *pos, int n)
479 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
480 return afns_compute (afns, n);
483 static AutoFiller *
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;
499 res->as.phases = 1;
501 return &res->filler;
504 /* ------------------------------------------------------------------------- */
506 * Month sequences:
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, ...
513 typedef struct {
514 AutoFiller filler;
516 GODateConventions const *dateconv;
517 GDate base;
518 GOFormat *format;
519 int nmonths;
520 gboolean end_of_month, same_of_month;
521 } AutoFillerMonth;
523 static void
524 afm_finalize (AutoFiller *af)
526 AutoFillerMonth *afm = (AutoFillerMonth *)af;
527 go_format_unref (afm->format);
528 af_finalize (af);
531 static void
532 afm_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
534 AutoFillerMonth *afm = (AutoFillerMonth *)af;
535 GnmValue *value = cell ? cell->value : NULL;
536 GDate d;
537 const GOFormat *sf;
539 if (value == NULL || gnm_cell_has_expr (cell)) {
540 bad:
541 af->status = AFS_ERROR;
542 return;
545 sf = gnm_cell_get_format (cell);
546 if (gnm_format_is_date_for_value (sf, value) != 1)
547 goto bad;
549 afm->dateconv = workbook_date_conv (cell->base.sheet->workbook);
550 if (!datetime_value_to_g (&d, value, afm->dateconv))
551 goto bad;
553 if (!g_date_is_last_of_month (&d))
554 afm->end_of_month = FALSE;
556 if (n == 0) {
557 if (VALUE_FMT (value))
558 afm->format = go_format_ref (VALUE_FMT (value));
559 afm->base = d;
560 } else {
561 int year = g_date_get_year (&d);
562 int month = g_date_get_month (&d);
563 int day = g_date_get_day (&d);
564 int nmonths;
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)
570 goto bad;
572 nmonths = 12 * (year - g_date_get_year (&afm->base)) +
573 (month - g_date_get_month (&afm->base));
574 if (n == 1)
575 afm->nmonths = nmonths;
576 else if (nmonths != afm->nmonths * n)
577 goto bad;
579 af->status = AFS_READY;
583 static GnmValue *
584 afm_compute (AutoFillerMonth *afm, int n)
586 GDate d = afm->base;
587 GnmValue *v;
589 gnm_date_add_months (&d, n * afm->nmonths);
591 if (!g_date_valid (&d) || g_date_get_year (&d) > 9999)
592 return NULL;
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));
601 if (afm->format)
602 value_set_fmt (v, afm->format);
603 return v;
606 static void
607 afm_set_cell (AutoFiller *af, GnmCell *cell, int n)
609 AutoFillerMonth *afm = (AutoFillerMonth *)af;
610 GnmValue *v = afm_compute (afm, n);
612 if (v)
613 gnm_cell_set_value (cell, v);
614 else {
615 GnmEvalPos ep;
616 eval_pos_init_cell (&ep, cell);
617 gnm_cell_set_value (cell, value_new_error_VALUE (&ep));
621 static char *
622 afm_hint (AutoFiller *af, GnmCellPos *pos, int n)
624 AutoFillerMonth *afm = (AutoFillerMonth *)af;
625 GnmValue *v = afm_compute (afm, n);
626 char *res = NULL;
628 if (v) {
629 res = format_value (NULL, v, -1, afm->dateconv);
630 value_release (v);
633 return res;
636 static AutoFiller *
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;
647 res->format = NULL;
648 res->dateconv = NULL;
649 res->end_of_month = TRUE;
650 res->same_of_month = TRUE;
652 return &res->filler;
655 /* ------------------------------------------------------------------------- */
657 typedef struct {
658 AutoFiller filler;
660 char **list;
661 gboolean with_number;
662 ArithString as;
663 } AutoFillerList;
665 static void
666 afl_finalize (AutoFiller *af)
668 AutoFillerList *afl = (AutoFillerList *)af;
669 as_finalize (&afl->as);
670 af_finalize (af);
673 static int
674 afl_compute_phase (AutoFillerList *afl, int n)
676 return (int)(n * afl->as.step + afl->as.base_phase) %
677 afl->as.phases;
680 static void
681 afl_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
683 AutoFillerList *afl = (AutoFillerList *)af;
684 GnmValue *value = cell ? cell->value : NULL;
685 char const *s;
686 gsize elen = 0;
687 int ph;
689 if (value == NULL ||
690 gnm_cell_has_expr (cell) ||
691 !VALUE_IS_STRING (value)) {
692 bad:
693 af->status = AFS_ERROR;
694 return;
697 s = value_peek_string (value);
698 for (ph = 0; ph < afl->as.phases; ph++) {
699 char const *e = afl->list[ph];
700 elen = strlen (e);
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)
705 break;
707 if (ph == afl->as.phases)
708 goto bad;
710 if (n == 0) {
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))
717 goto bad;
718 } else {
719 if (s[elen] != 0)
720 goto bad;
722 } else {
723 if (afl->with_number) {
724 if (as_teach_rest (&afl->as, s + elen, n, ph))
725 goto bad;
726 } else {
727 if (s[elen] != 0)
728 goto bad;
730 if (n == 1) {
731 int step = ph - afl->as.base_phase;
732 if (step == 0)
733 goto bad;
734 if (step < 0)
735 step += afl->as.phases;
736 afl->as.step = step;
737 } else {
738 if (ph != afl_compute_phase (afl, n))
739 goto bad;
743 af->status = AFS_READY;
747 static char *
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);
755 g_free (s);
758 return g_string_free (res, FALSE);
761 static void
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);
770 static char *
771 afl_hint (AutoFiller *af, GnmCellPos *pos, int n)
773 AutoFillerList *afl = (AutoFillerList *)af;
774 return afl_compute (afl, n);
777 static AutoFiller *
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;
788 res->list = list;
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;
795 return &res->filler;
798 /* ------------------------------------------------------------------------- */
800 typedef struct {
801 AutoFiller filler;
803 int size;
804 GnmCellPos last;
805 const GnmCell ** cells;
806 } AutoFillerCopy;
808 static void
809 afc_finalize (AutoFiller *af)
811 AutoFillerCopy *afe = (AutoFillerCopy *)af;
812 g_free (afe->cells);
813 af_finalize (af);
816 static void
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;
827 static char *
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];
833 char *res = NULL;
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))
842 return 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,
849 pos->col, pos->row);
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;
858 int cols, rows;
860 gnm_expr_top_get_array_size (texpr, &cols, &rows);
861 cols = MIN (limit_x, cols);
862 rows = MIN (limit_y, rows);
864 if (texpr) {
865 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (texpr));
866 gnm_expr_top_unref (texpr);
867 } else
868 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr));
870 if (doit)
871 gnm_cell_set_array_formula
872 (cell->base.sheet,
873 pos->col, cell->pos.row,
874 pos->col + (cols - 1),
875 pos->row + (rows - 1),
876 gnm_expr_top_new (aexpr));
877 else {
878 res = gnm_expr_as_string (aexpr,
879 &rinfo.pos,
880 sheet->convs);
881 gnm_expr_free (aexpr);
883 } else if (texpr) {
884 if (doit)
885 gnm_cell_set_expr (cell, texpr);
886 else
887 res = gnm_expr_top_as_string (texpr,
888 &rinfo.pos,
889 sheet->convs);
890 gnm_expr_top_unref (texpr);
891 } else {
892 if (doit)
893 gnm_cell_set_expr (cell, src_texpr);
894 else
895 res = gnm_expr_top_as_string (src_texpr,
896 &rinfo.pos,
897 sheet->convs);
899 } else if (src) {
900 if (doit)
901 gnm_cell_set_value (cell, value_dup (src->value));
902 else {
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,
908 dateconv);
910 } else {
911 if (doit)
912 sheet_cell_remove (cell->base.sheet, cell, TRUE, TRUE);
913 else
914 res = g_strdup (_("(empty)"));
917 return res;
920 static void
921 afc_set_cell (AutoFiller *af, GnmCell *cell, int n)
923 afc_set_cell_hint (af, cell, &cell->pos, n, TRUE);
926 static char *
927 afc_hint (AutoFiller *af, GnmCellPos *pos, int n)
929 return afc_set_cell_hint (af, NULL, pos, n, FALSE);
932 static AutoFiller *
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;
943 res->size = size;
944 res->last.col = last_col;
945 res->last.row = last_row;
946 res->cells = g_new0 (GnmCell const *, size);
948 return &res->filler;
951 /* ------------------------------------------------------------------------- */
953 static int
954 calc_steps (const GnmRange *r, int col_inc, int row_inc)
956 if (r)
957 return col_inc
958 ? range_width (r) / ABS (col_inc)
959 : range_height (r) / ABS (row_inc);
960 else
961 return 1;
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.
973 static char *
974 sheet_autofill_dir (Sheet *sheet, gboolean singleton,
975 int base_col, int base_row,
976 int region_size,
977 int count_max,
978 int col_inc, int row_inc,
979 int last_col, int last_row,
980 gboolean doit)
982 GList *fillers = NULL;
983 GList *f;
984 int i, j, true_region_size;
985 AutoFiller *af = NULL;
986 GnmStyle const **styles;
987 GnmRange const **merges;
988 int *merge_size;
989 char *hint = NULL;
990 gboolean reverse;
992 if (count_max <= 0 || region_size <= 0)
993 return NULL;
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
1013 * in this pass.
1015 merge_size = g_new0 (int, region_size);
1016 reverse = (col_inc < 0 || row_inc < 0);
1017 i = j = 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;
1023 GnmCellPos pos;
1024 int di;
1026 if (styles) {
1027 styles[j2] = sheet_style_get (sheet, col2, row2);
1028 gnm_style_ref (styles[j2]);
1031 pos.col = col2;
1032 pos.row = row2;
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;
1036 i += di;
1037 j++;
1039 true_region_size = j;
1041 /* We didn't know true_region_size up there. Patch up things. */
1042 if (reverse) {
1043 memmove (merge_size,
1044 merge_size + (region_size - true_region_size),
1045 true_region_size * sizeof (*merge_size));
1046 memmove (merges,
1047 merges + (region_size - true_region_size),
1048 true_region_size * sizeof (*merges));
1049 if (styles)
1050 memmove (styles,
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;
1089 GnmCell *cell;
1090 GList *f = fillers;
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);
1098 while (f) {
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);
1106 af->finalize (af);
1109 f = next;
1112 i += (ms + 1);
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)) {
1120 af = af1;
1124 if (!af) {
1125 /* Strange, but no fill. */
1126 } else if (doit) {
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;
1132 GnmCell *cell;
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]));
1143 if (merges[k]) {
1144 GnmRange r = *merges[k];
1145 int ofs = (i / region_size) * region_size;
1146 range_translate (&r, sheet,
1147 ofs * col_inc,
1148 ofs * row_inc);
1149 gnm_sheet_merge_add (sheet, &r, FALSE, NULL);
1151 i += (ms + 1);
1152 j++;
1154 } else {
1155 GnmCellPos pos;
1156 int repeats = (count_max - 1) / region_size;
1157 i = repeats * region_size;
1158 j = 0;
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;
1163 i += (ms + 1);
1164 j++;
1167 hint = af->hint (af, &pos, repeats * true_region_size + j - 1);
1170 while (fillers) {
1171 AutoFiller *af = fillers->data;
1172 fillers = g_list_delete_link (fillers, fillers);
1173 af->finalize (af);
1176 if (styles) {
1177 int i;
1178 for (i = 0; i < true_region_size; i++)
1179 if (styles[i])
1180 gnm_style_unref (styles[i]);
1181 g_free (styles);
1184 g_free (merges);
1185 g_free (merge_size);
1187 return hint;
1190 static void
1191 add_item (GString *dst, char *item, char const *sep)
1193 if (!dst) return;
1194 if (dst->len)
1195 g_string_append (dst, sep);
1196 if (item) {
1197 g_string_append (dst, item);
1198 g_free (item);
1199 } else
1200 g_string_append (dst, "?");
1203 static GString *
1204 sheet_autofill_internal (Sheet *sheet, gboolean singleton,
1205 int base_col, int base_row,
1206 int w, int h,
1207 int end_col, int end_row,
1208 gboolean doit)
1210 int series = 0;
1211 int right_col = MAX (base_col, end_col);
1212 int bottom_row = MAX (base_row, end_row);
1213 GString *res = NULL;
1214 GnmCellPos pos;
1215 GnmRange const *mr;
1217 g_return_val_if_fail (IS_SHEET (sheet), NULL);
1219 if (!doit)
1220 res = g_string_new (NULL);
1222 pos.col = base_col;
1223 pos.row = base_row;
1225 if (base_col > end_col || base_row > end_row) {
1226 if (base_col != end_col + w - 1) {
1227 /* LEFT */
1228 while (series < h) {
1229 add_item (res,
1230 sheet_autofill_dir (sheet, singleton,
1231 base_col, base_row - series,
1232 w, ABS (base_col - (end_col - 1)),
1233 -1, 0,
1234 right_col, bottom_row,
1235 doit),
1236 "\n");
1238 pos.row = base_row - series;
1239 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1240 series += mr ? range_height (mr) : 1;
1242 } else {
1243 /* UP */
1244 while (series < w) {
1245 add_item (res,
1246 sheet_autofill_dir (sheet, singleton,
1247 base_col - series, base_row,
1248 h, ABS (base_row - (end_row - 1)),
1249 0, -1,
1250 right_col, bottom_row,
1251 doit),
1252 " | ");
1254 pos.col = base_col - series;
1255 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1256 series += mr ? range_width (mr) : 1;
1259 } else {
1260 if (end_col != base_col + w - 1) {
1261 /* RIGHT */
1262 while (series < h) {
1263 add_item (res,
1264 sheet_autofill_dir (sheet, singleton,
1265 base_col, base_row + series,
1266 w, ABS (base_col - (end_col + 1)),
1267 1, 0,
1268 right_col, bottom_row,
1269 doit),
1270 "\n");
1272 pos.row = base_row + series;
1273 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1274 series += mr ? range_height (mr) : 1;
1276 } else {
1277 /* DOWN */
1278 while (series < w) {
1279 add_item (res,
1280 sheet_autofill_dir (sheet, singleton,
1281 base_col + series, base_row,
1282 h, ABS (base_row - (end_row + 1)),
1283 0, 1,
1284 right_col, bottom_row,
1285 doit),
1286 " | ");
1287 pos.col = base_col + series;
1288 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1289 series += mr ? range_width (mr) : 1;
1294 return res;
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.
1305 void
1306 gnm_autofill_fill (Sheet *sheet, gboolean singleton,
1307 int base_col, int base_row,
1308 int w, int h,
1309 int end_col, int end_row)
1311 sheet_autofill_internal (sheet, singleton,
1312 base_col, base_row,
1313 w, h,
1314 end_col, end_row,
1315 TRUE);
1318 GString *
1319 gnm_autofill_hint (Sheet *sheet, gboolean default_increment,
1320 int base_col, int base_row,
1321 int w, int h,
1322 int end_col, int end_row)
1324 return sheet_autofill_internal (sheet, default_increment,
1325 base_col, base_row,
1326 w, h,
1327 end_col, end_row,
1328 FALSE);