GUI: Move .ui files from goffice resources to glib resources
[gnumeric.git] / src / sheet-autofill.c
blob494cd1a8e2cd87bbadd925cfc2b8960187690ffb
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 /**
42 * gnm_autofill_init: (skip)
44 void
45 gnm_autofill_init (void)
47 GDateMonth m;
48 GDateWeekday wd;
49 char const *qtemplate;
51 for (m = 1; m <= 12; m++) {
52 month_names_long[m - 1] = go_date_month_name (m, FALSE);
53 month_names_short[m - 1] = go_date_month_name (m, TRUE);
55 for (wd = 1; wd <= 7; wd++) {
56 weekday_names_long[wd - 1] = go_date_weekday_name (wd, FALSE);
57 weekday_names_short[wd - 1] = go_date_weekday_name (wd, TRUE);
60 /* xgettext: This is a C format string where %d will be replaced
61 by 1, 2, 3, or 4. A year will then be appended and we'll get
62 something like 3Q2005. If that makes no sense in your language,
63 translate to the empty string. */
64 qtemplate = _("%dQ");
65 has_quarters = (qtemplate[0] != 0);
66 if (has_quarters) {
67 int q;
68 for (q = 1; q <= 4; q++)
69 quarters[q - 1] = g_strdup_printf (qtemplate, q);
73 /**
74 * gnm_autofill_shutdown: (skip)
76 void
77 gnm_autofill_shutdown (void)
79 GDateMonth m;
80 GDateWeekday wd;
81 int q;
83 for (m = 1; m <= 12; m++) {
84 g_free (month_names_long[m - 1]);
85 g_free (month_names_short[m - 1]);
87 for (wd = 1; wd <= 7; wd++) {
88 g_free (weekday_names_long[wd - 1]);
89 g_free (weekday_names_short[wd - 1]);
91 for (q = 1; q <= 4; q++)
92 g_free (quarters[q - 1]);
95 /* ------------------------------------------------------------------------- */
97 typedef enum {
98 AFS_INCOMPLETE,
99 AFS_READY,
100 AFS_ERROR
101 } AutoFillerStatus;
103 typedef struct _AutoFiller AutoFiller;
105 struct _AutoFiller {
106 AutoFillerStatus status;
107 int priority;
109 void (*finalize) (AutoFiller *af);
111 /* Given a new cell, adapt filler to that. */
112 void (*teach_cell) (AutoFiller *af, const GnmCell *cell, int n);
114 /* Set cell to the value of the nth sequence member. */
115 void (*set_cell) (AutoFiller *af, GnmCell *cell, int n);
117 /* Hint of what will be the nth element. */
118 char * (*hint) (AutoFiller *af, GnmCellPos *pos, int n);
121 static void
122 af_finalize (AutoFiller *af)
124 g_free (af);
127 /* ------------------------------------------------------------------------- */
129 * Arithmetic sequences:
131 * 1, 2, 3, ...
132 * 1, 3, 5, ....
133 * 1-Jan-2009, 2-Jan-2009, 3-Jan-2009, ...
134 * 1-Jan-2009, 8-Jan-2009, 15-Jan-2009, ...
135 * 00:00, 00:30, 01:00, ...
138 typedef struct {
139 AutoFiller filler;
141 gboolean singleton; /* Missing step becomes 1. */
142 gnm_float base, step;
143 GOFormat *format;
144 GODateConventions const *dateconv;
145 } AutoFillerArithmetic;
147 static void
148 afa_finalize (AutoFiller *af)
150 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
151 go_format_unref (afa->format);
152 af_finalize (af);
155 static void
156 afa_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
158 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
159 GnmValue *value = cell ? cell->value : NULL;
160 gnm_float f;
162 if (value == NULL ||
163 gnm_cell_has_expr (cell) ||
164 !VALUE_IS_NUMBER (value) ||
165 VALUE_IS_BOOLEAN (value)) {
166 af->status = AFS_ERROR;
167 return;
170 f = value_get_as_float (value);
172 switch (n) {
173 case 0:
174 afa->dateconv = sheet_date_conv (cell->base.sheet);
175 afa->base = f;
176 if (afa->singleton) {
177 afa->step = 1;
178 af->status = AFS_READY;
180 if (VALUE_FMT (value))
181 afa->format = go_format_ref (VALUE_FMT (value));
182 break;
183 case 1:
184 afa->step = f - afa->base;
185 af->status = AFS_READY;
186 break;
187 default: {
188 gnm_float step2 = (f - afa->base) / n;
189 gnm_float step_sum = gnm_abs (afa->step) + gnm_abs (step2);
190 gnm_float err = step_sum
191 ? gnm_abs (afa->step - step2) / step_sum
192 : 0;
193 /* Be fairly lenient: */
194 if (err > (n + 64) * GNM_EPSILON) {
195 af->status = AFS_ERROR;
196 return;
202 static GnmValue *
203 afa_compute (AutoFillerArithmetic *afa, int n)
205 gnm_float f = afa->base + n * afa->step;
206 GnmValue *v = value_new_float (f);
207 if (afa->format)
208 value_set_fmt (v, afa->format);
209 return v;
212 static void
213 afa_set_cell (AutoFiller *af, GnmCell *cell, int n)
215 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
216 GnmValue *v = afa_compute (afa, n);
217 gnm_cell_set_value (cell, v);
220 static char *
221 afa_hint (AutoFiller *af, GnmCellPos *pos, int n)
223 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
224 GnmValue *v = afa_compute (afa, n);
225 char *res = format_value (NULL, v, -1, afa->dateconv);
226 value_release (v);
227 return res;
230 static AutoFiller *
231 auto_filler_arithmetic (gboolean singleton)
233 AutoFillerArithmetic *res = g_new (AutoFillerArithmetic, 1);
235 res->filler.status = AFS_INCOMPLETE;
236 res->filler.priority = 100;
237 res->filler.finalize = afa_finalize;
238 res->filler.teach_cell = afa_teach_cell;
239 res->filler.set_cell = afa_set_cell;
240 res->filler.hint = afa_hint;
241 res->format = NULL;
242 res->dateconv = NULL;
243 res->singleton = singleton;
245 return &res->filler;
248 /* ------------------------------------------------------------------------- */
250 typedef struct {
251 gnm_float base, step;
252 GString *prefix, *suffix;
253 gboolean fixed_length;
254 int base_phase, phases;
255 gsize numlen;
256 gnm_float p10;
257 } ArithString;
259 static void
260 as_finalize (ArithString *as)
262 if (as->prefix)
263 g_string_free (as->prefix, TRUE);
264 if (as->suffix)
265 g_string_free (as->suffix, TRUE);
268 static gboolean
269 as_check_prefix_suffix (ArithString *as, char const *s, gsize slen)
271 if (as->prefix) {
272 if (slen < as->prefix->len ||
273 memcmp (s, as->prefix->str, as->prefix->len) != 0)
274 return TRUE;
275 s += as->prefix->len;
276 slen -= as->prefix->len;
279 if (as->suffix) {
280 if (slen < as->suffix->len ||
281 memcmp (s + slen - as->suffix->len,
282 as->suffix->str,
283 as->suffix->len) != 0)
284 return TRUE;
287 return FALSE;
290 static gnm_float
291 as_compute_val (ArithString *as, int n)
293 int pn = (n * as->step + as->base_phase) / as->phases;
294 gnm_float f = as->base + pn;
295 if (as->fixed_length)
296 f = gnm_fmod (f, as->p10);
297 return f;
300 static char *
301 as_compute (ArithString *as, int n)
303 gnm_float f = as_compute_val (as, n);
304 char const *prefix = as->prefix ? as->prefix->str : "";
305 char const *suffix = as->suffix ? as->suffix->str : "";
307 if (as->fixed_length) {
308 return g_strdup_printf ("%s%0*.0" GNM_FORMAT_f "%s",
309 prefix,
310 (int)as->numlen, f,
311 suffix);
312 } else {
313 return g_strdup_printf ("%s%.0" GNM_FORMAT_f "%s",
314 prefix,
316 suffix);
320 static gboolean
321 as_teach_first (ArithString *as, char const *s)
323 gsize pl;
324 char *end;
326 for (pl = 0; s[pl]; pl++) {
327 if (g_ascii_isdigit (s[pl]))
328 break;
329 if (!as->fixed_length &&
330 (s[pl] == '+' || s[pl] == '-') &&
331 g_ascii_isdigit (s[pl + 1]))
332 break;
334 if (s[pl] == 0)
335 return TRUE;
337 if (pl > 0) {
338 if (as->prefix)
339 g_string_append_len (as->prefix, s, pl);
340 else
341 return TRUE; /* No prefix allowed. */
343 errno = 0;
344 as->base = strtol (s + pl, &end, 10);
345 as->step = 1;
346 if (errno)
347 return TRUE;
348 if (*end) {
349 if (as->suffix)
350 g_string_append (as->suffix, end);
351 else
352 return TRUE; /* No suffix allowed. */
355 as->numlen = end - (s + pl);
356 as->p10 = gnm_pow10 (as->numlen);
358 return FALSE;
361 static gboolean
362 as_teach_rest (ArithString *as, char const *s, int n, int phase)
364 gsize slen = strlen (s);
365 char *end;
366 gnm_float val;
367 char const *s2 = s + (as->prefix ? as->prefix->len : 0);
369 if (as_check_prefix_suffix (as, s, slen))
370 return TRUE;
372 if (g_ascii_isspace (*s2))
373 return TRUE;
375 errno = 0;
376 if (as->fixed_length) {
377 if (!g_ascii_isdigit (*s2))
378 return TRUE;
379 val = strtol (s2, &end, 10);
380 if (as->numlen != (gsize)(end - s2))
381 return TRUE;
382 } else {
384 * Verify no leading zero so the fixed-length
385 * version gets a chance.
387 char const *s3 = s2;
388 if (!g_ascii_isdigit (*s3))
389 s3++;
390 if (s3[0] == '0' && g_ascii_isdigit (s3[1]))
391 return TRUE;
392 val = strtol (s2, &end, 10);
395 if (errno == ERANGE || end != s + slen - (as->suffix ? as->suffix->len : 0))
396 return TRUE;
398 if (n == 1) {
399 as->step = (val - as->base) * as->phases + (phase - as->base_phase);
400 if (as->fixed_length && as->step < 0)
401 as->step += as->p10 * as->phases;
402 } else {
403 gnm_float f = as_compute_val (as, n);
404 if (gnm_abs (f - val) > 0.5)
405 return TRUE;
408 return FALSE;
411 /* ------------------------------------------------------------------------- */
414 * Arithmetic sequences in strings:
416 * "Foo 1", "Foo 2", "Foo 3", ...
417 * "1 Bar", "3 Bar", "5 Bar", ...
418 * "Fall '99", "Fall '00", "Fall '01", ...
421 typedef struct {
422 AutoFiller filler;
424 gboolean singleton; /* Missing step becomes 1. */
425 ArithString as;
426 } AutoFillerNumberString;
428 static void
429 afns_finalize (AutoFiller *af)
431 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
432 as_finalize (&afns->as);
433 af_finalize (af);
436 static void
437 afns_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
439 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
440 GnmValue *value = cell ? cell->value : NULL;
441 char const *s;
443 if (value == NULL ||
444 gnm_cell_has_expr (cell) ||
445 !VALUE_IS_STRING (value)) {
446 bad:
447 af->status = AFS_ERROR;
448 return;
451 s = value_peek_string (value);
453 if (n == 0) {
454 if (as_teach_first (&afns->as, s))
455 goto bad;
457 if (afns->singleton)
458 af->status = AFS_READY;
459 } else {
460 if (as_teach_rest (&afns->as, s, n, 0))
461 goto bad;
463 af->status = AFS_READY;
467 static char *
468 afns_compute (AutoFillerNumberString *afns, int n)
470 return as_compute (&afns->as, n);
473 static void
474 afns_set_cell (AutoFiller *af, GnmCell *cell, int n)
476 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
477 char *s = afns_compute (afns, n);
478 gnm_cell_set_value (cell, value_new_string_nocopy (s));
481 static char *
482 afns_hint (AutoFiller *af, GnmCellPos *pos, int n)
484 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
485 return afns_compute (afns, n);
488 static AutoFiller *
489 auto_filler_number_string (gboolean singleton, gboolean fixed_length)
491 AutoFillerNumberString *res = g_new (AutoFillerNumberString, 1);
493 res->filler.status = AFS_INCOMPLETE;
494 res->filler.priority = fixed_length ? 9 : 10;
495 res->filler.finalize = afns_finalize;
496 res->filler.teach_cell = afns_teach_cell;
497 res->filler.set_cell = afns_set_cell;
498 res->filler.hint = afns_hint;
499 res->singleton = singleton;
500 res->as.fixed_length = fixed_length;
501 res->as.prefix = g_string_new (NULL);
502 res->as.suffix = g_string_new (NULL);
503 res->as.base_phase = 0;
504 res->as.phases = 1;
506 return &res->filler;
509 /* ------------------------------------------------------------------------- */
511 * Month sequences:
513 * 1-Jan-2009, 1-Feb-2009, 1-Mar-2009, ...
514 * 31-Jan-2009, 28-Feb-2009, 31-Mar-2009, ...
515 * 1-Jan-2009, 1-Jan-2010, 1-Jan-2011, ...
518 typedef struct {
519 AutoFiller filler;
521 GODateConventions const *dateconv;
522 GDate base;
523 GOFormat *format;
524 int nmonths;
525 gboolean end_of_month, same_of_month;
526 } AutoFillerMonth;
528 static void
529 afm_finalize (AutoFiller *af)
531 AutoFillerMonth *afm = (AutoFillerMonth *)af;
532 go_format_unref (afm->format);
533 af_finalize (af);
536 static void
537 afm_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
539 AutoFillerMonth *afm = (AutoFillerMonth *)af;
540 GnmValue *value = cell ? cell->value : NULL;
541 GDate d;
542 const GOFormat *sf;
544 if (value == NULL || gnm_cell_has_expr (cell)) {
545 bad:
546 af->status = AFS_ERROR;
547 return;
550 sf = gnm_cell_get_format (cell);
551 if (gnm_format_is_date_for_value (sf, value) != 1)
552 goto bad;
554 afm->dateconv = sheet_date_conv (cell->base.sheet);
555 if (!datetime_value_to_g (&d, value, afm->dateconv))
556 goto bad;
558 if (!g_date_is_last_of_month (&d))
559 afm->end_of_month = FALSE;
561 if (n == 0) {
562 if (VALUE_FMT (value))
563 afm->format = go_format_ref (VALUE_FMT (value));
564 afm->base = d;
565 } else {
566 int year = g_date_get_year (&d);
567 int month = g_date_get_month (&d);
568 int day = g_date_get_day (&d);
569 int nmonths;
571 if (day != g_date_get_day (&afm->base))
572 afm->same_of_month = FALSE;
574 if (!afm->same_of_month && !afm->end_of_month)
575 goto bad;
577 nmonths = 12 * (year - g_date_get_year (&afm->base)) +
578 (month - g_date_get_month (&afm->base));
579 if (n == 1)
580 afm->nmonths = nmonths;
581 else if (nmonths != afm->nmonths * n)
582 goto bad;
584 af->status = AFS_READY;
588 static GnmValue *
589 afm_compute (AutoFillerMonth *afm, int n)
591 GDate d = afm->base;
592 GnmValue *v;
594 gnm_date_add_months (&d, n * afm->nmonths);
596 if (!g_date_valid (&d) || g_date_get_year (&d) > 9999)
597 return NULL;
599 if (afm->end_of_month) {
600 int year = g_date_get_year (&d);
601 int month = g_date_get_month (&d);
602 g_date_set_day (&d, g_date_get_days_in_month (month, year));
605 v = value_new_int (go_date_g_to_serial (&d, afm->dateconv));
606 if (afm->format)
607 value_set_fmt (v, afm->format);
608 return v;
611 static void
612 afm_set_cell (AutoFiller *af, GnmCell *cell, int n)
614 AutoFillerMonth *afm = (AutoFillerMonth *)af;
615 GnmValue *v = afm_compute (afm, n);
617 if (v)
618 gnm_cell_set_value (cell, v);
619 else {
620 GnmEvalPos ep;
621 eval_pos_init_cell (&ep, cell);
622 gnm_cell_set_value (cell, value_new_error_VALUE (&ep));
626 static char *
627 afm_hint (AutoFiller *af, GnmCellPos *pos, int n)
629 AutoFillerMonth *afm = (AutoFillerMonth *)af;
630 GnmValue *v = afm_compute (afm, n);
631 char *res = NULL;
633 if (v) {
634 res = format_value (NULL, v, -1, afm->dateconv);
635 value_release (v);
638 return res;
641 static AutoFiller *
642 auto_filler_month (void)
644 AutoFillerMonth *res = g_new (AutoFillerMonth, 1);
646 res->filler.status = AFS_INCOMPLETE;
647 res->filler.priority = 200;
648 res->filler.finalize = afm_finalize;
649 res->filler.teach_cell = afm_teach_cell;
650 res->filler.set_cell = afm_set_cell;
651 res->filler.hint = afm_hint;
652 res->format = NULL;
653 res->dateconv = NULL;
654 res->end_of_month = TRUE;
655 res->same_of_month = TRUE;
657 return &res->filler;
660 /* ------------------------------------------------------------------------- */
662 typedef struct {
663 AutoFiller filler;
665 char **list;
666 gboolean with_number;
667 ArithString as;
668 } AutoFillerList;
670 static void
671 afl_finalize (AutoFiller *af)
673 AutoFillerList *afl = (AutoFillerList *)af;
674 as_finalize (&afl->as);
675 af_finalize (af);
678 static int
679 afl_compute_phase (AutoFillerList *afl, int n)
681 return (int)(n * afl->as.step + afl->as.base_phase) %
682 afl->as.phases;
685 static void
686 afl_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
688 AutoFillerList *afl = (AutoFillerList *)af;
689 GnmValue *value = cell ? cell->value : NULL;
690 char const *s;
691 gsize elen = 0;
692 int ph;
694 if (value == NULL ||
695 gnm_cell_has_expr (cell) ||
696 !VALUE_IS_STRING (value)) {
697 bad:
698 af->status = AFS_ERROR;
699 return;
702 s = value_peek_string (value);
703 for (ph = 0; ph < afl->as.phases; ph++) {
704 char const *e = afl->list[ph];
705 elen = strlen (e);
706 /* This isn't UTF-8 pretty. */
707 /* This isn't case pretty. */
708 /* This won't work if one list item is a prefix of another. */
709 if (strncmp (s, e, elen) == 0)
710 break;
712 if (ph == afl->as.phases)
713 goto bad;
715 if (n == 0) {
716 afl->as.base_phase = ph;
718 if (afl->with_number) {
719 afl->as.prefix = g_string_new (NULL);
720 afl->as.suffix = g_string_new (NULL);
721 if (as_teach_first (&afl->as, s + elen))
722 goto bad;
723 } else {
724 if (s[elen] != 0)
725 goto bad;
727 } else {
728 if (afl->with_number) {
729 if (as_teach_rest (&afl->as, s + elen, n, ph))
730 goto bad;
731 } else {
732 if (s[elen] != 0)
733 goto bad;
735 if (n == 1) {
736 int step = ph - afl->as.base_phase;
737 if (step == 0)
738 goto bad;
739 if (step < 0)
740 step += afl->as.phases;
741 afl->as.step = step;
742 } else {
743 if (ph != afl_compute_phase (afl, n))
744 goto bad;
748 af->status = AFS_READY;
752 static char *
753 afl_compute (AutoFillerList *afl, int n)
755 GString *res = g_string_new (afl->list[afl_compute_phase (afl, n)]);
757 if (afl->with_number) {
758 char *s = as_compute (&afl->as, n);
759 g_string_append (res, s);
760 g_free (s);
763 return g_string_free (res, FALSE);
766 static void
767 afl_set_cell (AutoFiller *af, GnmCell *cell, int n)
769 AutoFillerList *afl = (AutoFillerList *)af;
770 char *str = afl_compute (afl, n);
771 GnmValue *val = value_new_string_nocopy (str);
772 gnm_cell_set_value (cell, val);
775 static char *
776 afl_hint (AutoFiller *af, GnmCellPos *pos, int n)
778 AutoFillerList *afl = (AutoFillerList *)af;
779 return afl_compute (afl, n);
782 static AutoFiller *
783 auto_filler_list (char **list, int prio, gboolean with_number)
785 AutoFillerList *res = g_new (AutoFillerList, 1);
787 res->filler.status = AFS_INCOMPLETE;
788 res->filler.priority = prio;
789 res->filler.finalize = afl_finalize;
790 res->filler.teach_cell = afl_teach_cell;
791 res->filler.set_cell = afl_set_cell;
792 res->filler.hint = afl_hint;
793 res->list = list;
794 res->with_number = with_number;
795 res->as.phases = g_strv_length (list);
796 res->as.fixed_length = TRUE;
797 res->as.prefix = NULL;
798 res->as.suffix = NULL;
800 return &res->filler;
803 /* ------------------------------------------------------------------------- */
805 typedef struct {
806 AutoFiller filler;
808 int size;
809 GnmCellPos last;
810 const GnmCell ** cells;
811 } AutoFillerCopy;
813 static void
814 afc_finalize (AutoFiller *af)
816 AutoFillerCopy *afe = (AutoFillerCopy *)af;
817 g_free (afe->cells);
818 af_finalize (af);
821 static void
822 afc_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
824 AutoFillerCopy *afe = (AutoFillerCopy *)af;
825 afe->cells[n] = cell;
826 if (n == afe->size - 1) {
827 /* This actually includes the all-empty case. */
828 af->status = AFS_READY;
832 static char *
833 afc_set_cell_hint (AutoFiller *af, GnmCell *cell, GnmCellPos const *pos,
834 int n, gboolean doit)
836 AutoFillerCopy *afe = (AutoFillerCopy *)af;
837 GnmCell const *src = afe->cells[n % afe->size];
838 char *res = NULL;
839 if (src && gnm_cell_has_expr (src)) {
840 GnmExprRelocateInfo rinfo;
841 GnmExprTop const *texpr;
842 GnmExprTop const *src_texpr = src->base.texpr;
843 Sheet *sheet = src->base.sheet;
845 /* Arrays are always assigned fully at the corner. */
846 if (gnm_expr_top_is_array_elem (src_texpr, NULL, NULL))
847 return NULL;
849 rinfo.reloc_type = GNM_EXPR_RELOCATE_MOVE_RANGE;
850 rinfo.target_sheet = rinfo.origin_sheet = NULL;
851 rinfo.col_offset = rinfo.row_offset = 0;
852 rinfo.origin.start = rinfo.origin.end = *pos;
853 parse_pos_init (&rinfo.pos, sheet->workbook, sheet,
854 pos->col, pos->row);
856 texpr = gnm_expr_top_relocate (src_texpr, &rinfo, FALSE);
858 /* Clip arrays that are only partially copied. */
859 if (gnm_expr_top_is_array_corner (src_texpr)) {
860 GnmExpr const *aexpr;
861 int limit_x = afe->last.col - pos->col + 1;
862 int limit_y = afe->last.row - pos->row + 1;
863 int cols, rows;
865 gnm_expr_top_get_array_size (texpr, &cols, &rows);
866 cols = MIN (limit_x, cols);
867 rows = MIN (limit_y, rows);
869 if (texpr) {
870 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (texpr));
871 gnm_expr_top_unref (texpr);
872 } else
873 aexpr = gnm_expr_copy (gnm_expr_top_get_array_expr (src_texpr));
875 if (doit)
876 gnm_cell_set_array_formula
877 (cell->base.sheet,
878 pos->col, cell->pos.row,
879 pos->col + (cols - 1),
880 pos->row + (rows - 1),
881 gnm_expr_top_new (aexpr));
882 else {
883 res = gnm_expr_as_string (aexpr,
884 &rinfo.pos,
885 sheet->convs);
886 gnm_expr_free (aexpr);
888 } else if (texpr) {
889 if (doit)
890 gnm_cell_set_expr (cell, texpr);
891 else
892 res = gnm_expr_top_as_string (texpr,
893 &rinfo.pos,
894 sheet->convs);
895 gnm_expr_top_unref (texpr);
896 } else {
897 if (doit)
898 gnm_cell_set_expr (cell, src_texpr);
899 else
900 res = gnm_expr_top_as_string (src_texpr,
901 &rinfo.pos,
902 sheet->convs);
904 } else if (src) {
905 if (doit)
906 gnm_cell_set_value (cell, value_dup (src->value));
907 else {
908 Sheet const *sheet = src->base.sheet;
909 GODateConventions const *dateconv =
910 sheet_date_conv (sheet);
911 GOFormat const *format = gnm_cell_get_format (src);
912 return format_value (format, src->value, -1,
913 dateconv);
915 } else {
916 if (doit)
917 sheet_cell_remove (cell->base.sheet, cell, TRUE, TRUE);
918 else
919 res = g_strdup (_("(empty)"));
922 return res;
925 static void
926 afc_set_cell (AutoFiller *af, GnmCell *cell, int n)
928 afc_set_cell_hint (af, cell, &cell->pos, n, TRUE);
931 static char *
932 afc_hint (AutoFiller *af, GnmCellPos *pos, int n)
934 return afc_set_cell_hint (af, NULL, pos, n, FALSE);
937 static AutoFiller *
938 auto_filler_copy (int size, guint last_col, guint last_row)
940 AutoFillerCopy *res = g_new (AutoFillerCopy, 1);
942 res->filler.status = AFS_INCOMPLETE;
943 res->filler.priority = 1;
944 res->filler.finalize = afc_finalize;
945 res->filler.teach_cell = afc_teach_cell;
946 res->filler.set_cell = afc_set_cell;
947 res->filler.hint = afc_hint;
948 res->size = size;
949 res->last.col = last_col;
950 res->last.row = last_row;
951 res->cells = g_new0 (GnmCell const *, size);
953 return &res->filler;
956 /* ------------------------------------------------------------------------- */
958 static int
959 calc_steps (const GnmRange *r, int col_inc, int row_inc)
961 if (r)
962 return col_inc
963 ? range_width (r) / ABS (col_inc)
964 : range_height (r) / ABS (row_inc);
965 else
966 return 1;
971 * (base_col,base_row): start of source area.
972 * (col_inc,row_inc): direction of fill.
973 * count_max: size of source+fill area in direction of fill.
974 * region_size: size of source area in direction of fill.
975 * (last_col,last_row): last cell of entire area being filled.
978 static char *
979 sheet_autofill_dir (Sheet *sheet, gboolean singleton,
980 int base_col, int base_row,
981 int region_size,
982 int count_max,
983 int col_inc, int row_inc,
984 int last_col, int last_row,
985 gboolean doit)
987 GList *fillers = NULL;
988 GList *f;
989 int i, j, true_region_size;
990 AutoFiller *af = NULL;
991 GnmStyle const **styles;
992 GnmRange const **merges;
993 int *merge_size;
994 char *hint = NULL;
995 gboolean reverse;
997 if (count_max <= 0 || region_size <= 0)
998 return NULL;
1001 * These are both indexed by cell number in the sequence we see
1002 * cells. I.e., they go 0, 1, 2, ... no matter what way we fill
1003 * and no matter if some cells are merged.
1005 * The allocations may be larger than we need, but we don't know
1006 * the right size yet.
1008 styles = doit ? g_new0 (GnmStyle const *, region_size) : NULL;
1009 merges = g_new0 (GnmRange const *, region_size);
1012 * i counts rows/cols.
1013 * j follows, but skips hidden parts of merged cells.
1017 * Pass 1: Have a look at the merges. We always go right or down
1018 * in this pass.
1020 merge_size = g_new0 (int, region_size);
1021 reverse = (col_inc < 0 || row_inc < 0);
1022 i = j = 0;
1023 while (i < region_size) {
1024 int i2 = (reverse ? region_size - 1 - i : i);
1025 int j2 = (reverse ? /*true_*/region_size - 1 - j : j);
1026 int col2 = base_col + i2 * col_inc;
1027 int row2 = base_row + i2 * row_inc;
1028 GnmCellPos pos;
1029 int di;
1031 if (styles) {
1032 styles[j2] = sheet_style_get (sheet, col2, row2);
1033 gnm_style_ref (styles[j2]);
1036 pos.col = col2;
1037 pos.row = row2;
1038 merges[j2] = gnm_sheet_merge_contains_pos (sheet, &pos);
1039 di = calc_steps (merges[j2], col_inc, row_inc);
1040 merge_size[j2] = di - 1;
1041 i += di;
1042 j++;
1044 true_region_size = j;
1046 /* We didn't know true_region_size up there. Patch up things. */
1047 if (reverse) {
1048 memmove (merge_size,
1049 merge_size + (region_size - true_region_size),
1050 true_region_size * sizeof (*merge_size));
1051 memmove (merges,
1052 merges + (region_size - true_region_size),
1053 true_region_size * sizeof (*merges));
1054 if (styles)
1055 memmove (styles,
1056 styles + (region_size - true_region_size),
1057 true_region_size * sizeof (*styles));
1060 fillers = g_list_prepend
1061 (fillers, auto_filler_arithmetic (singleton));
1062 fillers = g_list_prepend
1063 (fillers, auto_filler_number_string (singleton, TRUE));
1064 fillers = g_list_prepend
1065 (fillers, auto_filler_number_string (singleton, FALSE));
1066 fillers = g_list_prepend
1067 (fillers, auto_filler_month ());
1068 fillers = g_list_prepend
1069 (fillers, auto_filler_copy (true_region_size,
1070 last_col, last_row));
1071 fillers = g_list_prepend (fillers, auto_filler_list (quarters, 50, TRUE));
1073 fillers = g_list_prepend
1074 (fillers, auto_filler_list (month_names_long, 61, TRUE));
1075 fillers = g_list_prepend
1076 (fillers, auto_filler_list (month_names_short, 51, TRUE));
1077 fillers = g_list_prepend
1078 (fillers, auto_filler_list (month_names_long, 61, FALSE));
1079 fillers = g_list_prepend
1080 (fillers, auto_filler_list (month_names_short, 51, FALSE));
1081 fillers = g_list_prepend
1082 (fillers, auto_filler_list (weekday_names_long, 60, FALSE));
1083 fillers = g_list_prepend
1084 (fillers, auto_filler_list (weekday_names_short, 50, FALSE));
1087 * Pass 2: Present all cells to the fillers and remove fillers that
1088 * cannot handle the contents.
1090 for (i = j = 0; j < true_region_size; j++) {
1091 int ms = merge_size[j];
1092 int col = base_col + i * col_inc;
1093 int row = base_row + i * row_inc;
1094 GnmCell *cell;
1095 GList *f = fillers;
1097 if (reverse && merges[j]) {
1098 col -= range_width (merges[j]) - 1;
1099 row -= range_height (merges[j]) - 1;
1101 cell = sheet_cell_get (sheet, col, row);
1103 while (f) {
1104 AutoFiller *af = f->data;
1105 GList *next = f->next;
1107 af->teach_cell (af, cell, j);
1109 if (af->status == AFS_ERROR) {
1110 fillers = g_list_delete_link (fillers, f);
1111 af->finalize (af);
1114 f = next;
1117 i += (ms + 1);
1120 /* Find the best filler that's ready. */
1121 for (f = fillers; f; f = f->next) {
1122 AutoFiller *af1 = f->data;
1123 if (af1->status == AFS_READY &&
1124 (af == NULL || af1->priority > af->priority)) {
1125 af = af1;
1129 if (!af) {
1130 /* Strange, but no fill. */
1131 } else if (doit) {
1132 while (i < count_max) {
1133 int k = j % true_region_size;
1134 int ms = merge_size[k];
1135 int col = base_col + i * col_inc;
1136 int row = base_row + i * row_inc;
1137 GnmCell *cell;
1139 if (reverse && merges[k]) {
1140 col -= range_width (merges[k]) - 1;
1141 row -= range_height (merges[k]) - 1;
1143 cell = sheet_cell_fetch (sheet, col, row);
1144 af->set_cell (af, cell, j);
1146 sheet_style_set_pos (sheet, col, row,
1147 gnm_style_dup (styles[k]));
1148 if (merges[k]) {
1149 GnmRange r = *merges[k];
1150 int ofs = (i / region_size) * region_size;
1151 range_translate (&r, sheet,
1152 ofs * col_inc,
1153 ofs * row_inc);
1154 gnm_sheet_merge_add (sheet, &r, FALSE, NULL);
1156 i += (ms + 1);
1157 j++;
1159 } else {
1160 GnmCellPos pos;
1161 int repeats = (count_max - 1) / region_size;
1162 i = repeats * region_size;
1163 j = 0;
1164 while (i < count_max) {
1165 int ms = merge_size[j];
1166 pos.col = base_col + i * col_inc;
1167 pos.row = base_row + i * row_inc;
1168 i += (ms + 1);
1169 j++;
1172 hint = af->hint (af, &pos, repeats * true_region_size + j - 1);
1175 while (fillers) {
1176 AutoFiller *af = fillers->data;
1177 fillers = g_list_delete_link (fillers, fillers);
1178 af->finalize (af);
1181 if (styles) {
1182 int i;
1183 for (i = 0; i < true_region_size; i++)
1184 if (styles[i])
1185 gnm_style_unref (styles[i]);
1186 g_free (styles);
1189 g_free (merges);
1190 g_free (merge_size);
1192 return hint;
1195 static void
1196 add_item (GString *dst, char *item, char const *sep)
1198 if (!dst) return;
1199 if (dst->len)
1200 g_string_append (dst, sep);
1201 if (item) {
1202 g_string_append (dst, item);
1203 g_free (item);
1204 } else
1205 g_string_append (dst, "?");
1208 static GString *
1209 sheet_autofill_internal (Sheet *sheet, gboolean singleton,
1210 int base_col, int base_row,
1211 int w, int h,
1212 int end_col, int end_row,
1213 gboolean doit)
1215 int series = 0;
1216 int right_col = MAX (base_col, end_col);
1217 int bottom_row = MAX (base_row, end_row);
1218 GString *res = NULL;
1219 GnmCellPos pos;
1220 GnmRange const *mr;
1222 g_return_val_if_fail (IS_SHEET (sheet), NULL);
1224 if (!doit)
1225 res = g_string_new (NULL);
1227 pos.col = base_col;
1228 pos.row = base_row;
1230 if (base_col > end_col || base_row > end_row) {
1231 if (base_col != end_col + w - 1) {
1232 /* LEFT */
1233 while (series < h) {
1234 add_item (res,
1235 sheet_autofill_dir (sheet, singleton,
1236 base_col, base_row - series,
1237 w, ABS (base_col - (end_col - 1)),
1238 -1, 0,
1239 right_col, bottom_row,
1240 doit),
1241 "\n");
1243 pos.row = base_row - series;
1244 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1245 series += mr ? range_height (mr) : 1;
1247 } else {
1248 /* UP */
1249 while (series < w) {
1250 add_item (res,
1251 sheet_autofill_dir (sheet, singleton,
1252 base_col - series, base_row,
1253 h, ABS (base_row - (end_row - 1)),
1254 0, -1,
1255 right_col, bottom_row,
1256 doit),
1257 " | ");
1259 pos.col = base_col - series;
1260 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1261 series += mr ? range_width (mr) : 1;
1264 } else {
1265 if (end_col != base_col + w - 1) {
1266 /* RIGHT */
1267 while (series < h) {
1268 add_item (res,
1269 sheet_autofill_dir (sheet, singleton,
1270 base_col, base_row + series,
1271 w, ABS (base_col - (end_col + 1)),
1272 1, 0,
1273 right_col, bottom_row,
1274 doit),
1275 "\n");
1277 pos.row = base_row + series;
1278 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1279 series += mr ? range_height (mr) : 1;
1281 } else {
1282 /* DOWN */
1283 while (series < w) {
1284 add_item (res,
1285 sheet_autofill_dir (sheet, singleton,
1286 base_col + series, base_row,
1287 h, ABS (base_row - (end_row + 1)),
1288 0, 1,
1289 right_col, bottom_row,
1290 doit),
1291 " | ");
1292 pos.col = base_col + series;
1293 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1294 series += mr ? range_width (mr) : 1;
1299 return res;
1305 * gnm_autofill_fill:
1307 * An internal routine to autofill a region. It does NOT
1308 * queue a recalc, flag a status update, or regen spans.
1310 void
1311 gnm_autofill_fill (Sheet *sheet, gboolean singleton,
1312 int base_col, int base_row,
1313 int w, int h,
1314 int end_col, int end_row)
1316 sheet_autofill_internal (sheet, singleton,
1317 base_col, base_row,
1318 w, h,
1319 end_col, end_row,
1320 TRUE);
1323 GString *
1324 gnm_autofill_hint (Sheet *sheet, gboolean default_increment,
1325 int base_col, int base_row,
1326 int w, int h,
1327 int end_col, int end_row)
1329 return sheet_autofill_internal (sheet, default_increment,
1330 base_col, base_row,
1331 w, h,
1332 end_col, end_row,
1333 FALSE);