1 /*
2 * sheet-autofill.c: Provides the autofill features
3 *
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>
13
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>
26
27 #include <string.h>
28 #include <errno.h>
29 #include <stdlib.h>
30
31 /* ------------------------------------------------------------------------- */
32
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;
39
40 /**
41 * gnm_autofill_init: (skip)
42 */
43 void
gnm_autofill_init(void)44 gnm_autofill_init (void)
45 {
46 GDateMonth m;
47 GDateWeekday wd;
48 char const *qtemplate;
49
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);
53 }
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);
57 }
58
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);
69 }
70 }
71
72 /**
73 * gnm_autofill_shutdown: (skip)
74 */
75 void
gnm_autofill_shutdown(void)76 gnm_autofill_shutdown (void)
77 {
78 GDateMonth m;
79 GDateWeekday wd;
80 int q;
81
82 for (m = 1; m <= 12; m++) {
83 g_free (month_names_long[m - 1]);
84 g_free (month_names_short[m - 1]);
85 }
86 for (wd = 1; wd <= 7; wd++) {
87 g_free (weekday_names_long[wd - 1]);
88 g_free (weekday_names_short[wd - 1]);
89 }
90 for (q = 1; q <= 4; q++)
91 g_free (quarters[q - 1]);
92 }
93
94 /* ------------------------------------------------------------------------- */
95
96 typedef enum {
97 AFS_INCOMPLETE,
98 AFS_READY,
99 AFS_ERROR
100 } AutoFillerStatus;
101
102 typedef struct _AutoFiller AutoFiller;
103
104 struct _AutoFiller {
105 AutoFillerStatus status;
106 int priority;
107
108 void (*finalize) (AutoFiller *af);
109
110 /* Given a new cell, adapt filler to that. */
111 void (*teach_cell) (AutoFiller *af, const GnmCell *cell, int n);
112
113 /* Set cell to the value of the nth sequence member. */
114 void (*set_cell) (AutoFiller *af, GnmCell *cell, int n);
115
116 /* Hint of what will be the nth element. */
117 char * (*hint) (AutoFiller *af, GnmCellPos *pos, int n);
118 };
119
120 static void
af_finalize(AutoFiller * af)121 af_finalize (AutoFiller *af)
122 {
123 g_free (af);
124 }
125
126 /* ------------------------------------------------------------------------- */
127 /*
128 * Arithmetic sequences:
129 *
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, ...
135 */
136
137 typedef struct {
138 AutoFiller filler;
139
140 gboolean singleton; /* Missing step becomes 1. */
141 gnm_float base, step;
142 GOFormat *format;
143 GODateConventions const *dateconv;
144 } AutoFillerArithmetic;
145
146 static void
afa_finalize(AutoFiller * af)147 afa_finalize (AutoFiller *af)
148 {
149 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
150 go_format_unref (afa->format);
151 af_finalize (af);
152 }
153
154 static void
afa_teach_cell(AutoFiller * af,const GnmCell * cell,int n)155 afa_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
156 {
157 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
158 GnmValue *value = cell ? cell->value : NULL;
159 gnm_float f;
160
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;
167 }
168
169 f = value_get_as_float (value);
170
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;
178 }
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;
196 }
197 }
198 }
199 }
200
201 static GnmValue *
afa_compute(AutoFillerArithmetic * afa,int n)202 afa_compute (AutoFillerArithmetic *afa, int n)
203 {
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;
209 }
210
211 static void
afa_set_cell(AutoFiller * af,GnmCell * cell,int n)212 afa_set_cell (AutoFiller *af, GnmCell *cell, int n)
213 {
214 AutoFillerArithmetic *afa = (AutoFillerArithmetic *)af;
215 GnmValue *v = afa_compute (afa, n);
216 gnm_cell_set_value (cell, v);
217 }
218
219 static char *
afa_hint(AutoFiller * af,GnmCellPos * pos,int n)220 afa_hint (AutoFiller *af, GnmCellPos *pos, int n)
221 {
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;
227 }
228
229 static AutoFiller *
auto_filler_arithmetic(gboolean singleton)230 auto_filler_arithmetic (gboolean singleton)
231 {
232 AutoFillerArithmetic *res = g_new (AutoFillerArithmetic, 1);
233
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;
243
244 return &res->filler;
245 }
246
247 /* ------------------------------------------------------------------------- */
248
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;
257
258 static void
as_finalize(ArithString * as)259 as_finalize (ArithString *as)
260 {
261 if (as->prefix)
262 g_string_free (as->prefix, TRUE);
263 if (as->suffix)
264 g_string_free (as->suffix, TRUE);
265 }
266
267 static gboolean
as_check_prefix_suffix(ArithString * as,char const * s,gsize slen)268 as_check_prefix_suffix (ArithString *as, char const *s, gsize slen)
269 {
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;
276 }
277
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;
284 }
285
286 return FALSE;
287 }
288
289 static gnm_float
as_compute_val(ArithString * as,int n)290 as_compute_val (ArithString *as, int n)
291 {
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;
297 }
298
299 static char *
as_compute(ArithString * as,int n)300 as_compute (ArithString *as, int n)
301 {
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 : "";
305
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,
314 f,
315 suffix);
316 }
317 }
318
319 static gboolean
as_teach_first(ArithString * as,char const * s)320 as_teach_first (ArithString *as, char const *s)
321 {
322 gsize pl;
323 char *end;
324
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;
332 }
333 if (s[pl] == 0)
334 return TRUE;
335
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. */
341 }
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. */
352 }
353
354 as->numlen = end - (s + pl);
355 as->p10 = gnm_pow10 (as->numlen);
356
357 return FALSE;
358 }
359
360 static gboolean
as_teach_rest(ArithString * as,char const * s,int n,int phase)361 as_teach_rest (ArithString *as, char const *s, int n, int phase)
362 {
363 gsize slen = strlen (s);
364 char *end;
365 gnm_float val;
366 char const *s2 = s + (as->prefix ? as->prefix->len : 0);
367
368 if (as_check_prefix_suffix (as, s, slen))
369 return TRUE;
370
371 if (g_ascii_isspace (*s2))
372 return TRUE;
373
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 {
382 /*
383 * Verify no leading zero so the fixed-length
384 * version gets a chance.
385 */
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);
392 }
393
394 if (errno == ERANGE || end != s + slen - (as->suffix ? as->suffix->len : 0))
395 return TRUE;
396
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;
405 }
406
407 return FALSE;
408 }
409
410 /* ------------------------------------------------------------------------- */
411
412 /*
413 * Arithmetic sequences in strings:
414 *
415 * "Foo 1", "Foo 2", "Foo 3", ...
416 * "1 Bar", "3 Bar", "5 Bar", ...
417 * "Fall '99", "Fall '00", "Fall '01", ...
418 */
419
420 typedef struct {
421 AutoFiller filler;
422
423 gboolean singleton; /* Missing step becomes 1. */
424 ArithString as;
425 } AutoFillerNumberString;
426
427 static void
afns_finalize(AutoFiller * af)428 afns_finalize (AutoFiller *af)
429 {
430 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
431 as_finalize (&afns->as);
432 af_finalize (af);
433 }
434
435 static void
afns_teach_cell(AutoFiller * af,const GnmCell * cell,int n)436 afns_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
437 {
438 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
439 GnmValue *value = cell ? cell->value : NULL;
440 char const *s;
441
442 if (value == NULL ||
443 gnm_cell_has_expr (cell) ||
444 !VALUE_IS_STRING (value)) {
445 bad:
446 af->status = AFS_ERROR;
447 return;
448 }
449
450 s = value_peek_string (value);
451
452 if (n == 0) {
453 if (as_teach_first (&afns->as, s))
454 goto bad;
455
456 if (afns->singleton)
457 af->status = AFS_READY;
458 } else {
459 if (as_teach_rest (&afns->as, s, n, 0))
460 goto bad;
461
462 af->status = AFS_READY;
463 }
464 }
465
466 static char *
afns_compute(AutoFillerNumberString * afns,int n)467 afns_compute (AutoFillerNumberString *afns, int n)
468 {
469 return as_compute (&afns->as, n);
470 }
471
472 static void
afns_set_cell(AutoFiller * af,GnmCell * cell,int n)473 afns_set_cell (AutoFiller *af, GnmCell *cell, int n)
474 {
475 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
476 char *s = afns_compute (afns, n);
477 gnm_cell_set_value (cell, value_new_string_nocopy (s));
478 }
479
480 static char *
afns_hint(AutoFiller * af,GnmCellPos * pos,int n)481 afns_hint (AutoFiller *af, GnmCellPos *pos, int n)
482 {
483 AutoFillerNumberString *afns = (AutoFillerNumberString *)af;
484 return afns_compute (afns, n);
485 }
486
487 static AutoFiller *
auto_filler_number_string(gboolean singleton,gboolean fixed_length)488 auto_filler_number_string (gboolean singleton, gboolean fixed_length)
489 {
490 AutoFillerNumberString *res = g_new (AutoFillerNumberString, 1);
491
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;
504
505 return &res->filler;
506 }
507
508 /* ------------------------------------------------------------------------- */
509 /*
510 * Month sequences:
511 *
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, ...
515 */
516
517 typedef struct {
518 AutoFiller filler;
519
520 GODateConventions const *dateconv;
521 GDate base;
522 GOFormat *format;
523 int nmonths;
524 gboolean end_of_month, same_of_month;
525 } AutoFillerMonth;
526
527 static void
afm_finalize(AutoFiller * af)528 afm_finalize (AutoFiller *af)
529 {
530 AutoFillerMonth *afm = (AutoFillerMonth *)af;
531 go_format_unref (afm->format);
532 af_finalize (af);
533 }
534
535 static void
afm_teach_cell(AutoFiller * af,const GnmCell * cell,int n)536 afm_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
537 {
538 AutoFillerMonth *afm = (AutoFillerMonth *)af;
539 GnmValue *value = cell ? cell->value : NULL;
540 GDate d;
541 const GOFormat *sf;
542
543 if (value == NULL || gnm_cell_has_expr (cell)) {
544 bad:
545 af->status = AFS_ERROR;
546 return;
547 }
548
549 sf = gnm_cell_get_format (cell);
550 if (gnm_format_is_date_for_value (sf, value) != 1)
551 goto bad;
552
553 afm->dateconv = sheet_date_conv (cell->base.sheet);
554 if (!datetime_value_to_g (&d, value, afm->dateconv))
555 goto bad;
556
557 if (!g_date_is_last_of_month (&d))
558 afm->end_of_month = FALSE;
559
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;
569
570 if (day != g_date_get_day (&afm->base))
571 afm->same_of_month = FALSE;
572
573 if (!afm->same_of_month && !afm->end_of_month)
574 goto bad;
575
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;
582
583 af->status = AFS_READY;
584 }
585 }
586
587 static GnmValue *
afm_compute(AutoFillerMonth * afm,int n)588 afm_compute (AutoFillerMonth *afm, int n)
589 {
590 GDate d = afm->base;
591 GnmValue *v;
592
593 gnm_date_add_months (&d, n * afm->nmonths);
594
595 if (!g_date_valid (&d) || g_date_get_year (&d) > 9999)
596 return NULL;
597
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));
602 }
603
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;
608 }
609
610 static void
afm_set_cell(AutoFiller * af,GnmCell * cell,int n)611 afm_set_cell (AutoFiller *af, GnmCell *cell, int n)
612 {
613 AutoFillerMonth *afm = (AutoFillerMonth *)af;
614 GnmValue *v = afm_compute (afm, n);
615
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));
622 }
623 }
624
625 static char *
afm_hint(AutoFiller * af,GnmCellPos * pos,int n)626 afm_hint (AutoFiller *af, GnmCellPos *pos, int n)
627 {
628 AutoFillerMonth *afm = (AutoFillerMonth *)af;
629 GnmValue *v = afm_compute (afm, n);
630 char *res = NULL;
631
632 if (v) {
633 res = format_value (NULL, v, -1, afm->dateconv);
634 value_release (v);
635 }
636
637 return res;
638 }
639
640 static AutoFiller *
auto_filler_month(void)641 auto_filler_month (void)
642 {
643 AutoFillerMonth *res = g_new (AutoFillerMonth, 1);
644
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;
655
656 return &res->filler;
657 }
658
659 /* ------------------------------------------------------------------------- */
660
661 typedef struct {
662 AutoFiller filler;
663
664 char **list;
665 gboolean with_number;
666 ArithString as;
667 } AutoFillerList;
668
669 static void
afl_finalize(AutoFiller * af)670 afl_finalize (AutoFiller *af)
671 {
672 AutoFillerList *afl = (AutoFillerList *)af;
673 as_finalize (&afl->as);
674 af_finalize (af);
675 }
676
677 static int
afl_compute_phase(AutoFillerList * afl,int n)678 afl_compute_phase (AutoFillerList *afl, int n)
679 {
680 return (int)(n * afl->as.step + afl->as.base_phase) %
681 afl->as.phases;
682 }
683
684 static void
afl_teach_cell(AutoFiller * af,const GnmCell * cell,int n)685 afl_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
686 {
687 AutoFillerList *afl = (AutoFillerList *)af;
688 GnmValue *value = cell ? cell->value : NULL;
689 char const *s;
690 gsize elen = 0;
691 int ph;
692
693 if (value == NULL ||
694 gnm_cell_has_expr (cell) ||
695 !VALUE_IS_STRING (value)) {
696 bad:
697 af->status = AFS_ERROR;
698 return;
699 }
700
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;
710 }
711 if (ph == afl->as.phases)
712 goto bad;
713
714 if (n == 0) {
715 afl->as.base_phase = ph;
716
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;
725 }
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;
733
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;
744 }
745 }
746
747 af->status = AFS_READY;
748 }
749 }
750
751 static char *
afl_compute(AutoFillerList * afl,int n)752 afl_compute (AutoFillerList *afl, int n)
753 {
754 GString *res = g_string_new (afl->list[afl_compute_phase (afl, n)]);
755
756 if (afl->with_number) {
757 char *s = as_compute (&afl->as, n);
758 g_string_append (res, s);
759 g_free (s);
760 }
761
762 return g_string_free (res, FALSE);
763 }
764
765 static void
afl_set_cell(AutoFiller * af,GnmCell * cell,int n)766 afl_set_cell (AutoFiller *af, GnmCell *cell, int n)
767 {
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);
772 }
773
774 static char *
afl_hint(AutoFiller * af,GnmCellPos * pos,int n)775 afl_hint (AutoFiller *af, GnmCellPos *pos, int n)
776 {
777 AutoFillerList *afl = (AutoFillerList *)af;
778 return afl_compute (afl, n);
779 }
780
781 static AutoFiller *
auto_filler_list(char ** list,int prio,gboolean with_number)782 auto_filler_list (char **list, int prio, gboolean with_number)
783 {
784 AutoFillerList *res = g_new (AutoFillerList, 1);
785
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;
798
799 return &res->filler;
800 }
801
802 /* ------------------------------------------------------------------------- */
803
804 typedef struct {
805 AutoFiller filler;
806
807 int size;
808 GnmCellPos last;
809 const GnmCell ** cells;
810 } AutoFillerCopy;
811
812 static void
afc_finalize(AutoFiller * af)813 afc_finalize (AutoFiller *af)
814 {
815 AutoFillerCopy *afe = (AutoFillerCopy *)af;
816 g_free (afe->cells);
817 af_finalize (af);
818 }
819
820 static void
afc_teach_cell(AutoFiller * af,const GnmCell * cell,int n)821 afc_teach_cell (AutoFiller *af, const GnmCell *cell, int n)
822 {
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;
828 }
829 }
830
831 static char *
afc_set_cell_hint(AutoFiller * af,GnmCell * cell,GnmCellPos const * pos,int n,gboolean doit)832 afc_set_cell_hint (AutoFiller *af, GnmCell *cell, GnmCellPos const *pos,
833 int n, gboolean doit)
834 {
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;
843
844 /* Arrays are always assigned fully at the corner. */
845 if (gnm_expr_top_is_array_elem (src_texpr, NULL, NULL))
846 return NULL;
847
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);
854
855 texpr = gnm_expr_top_relocate (src_texpr, &rinfo, FALSE);
856
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;
863
864 gnm_expr_top_get_array_size (src_texpr, &cols, &rows);
865 cols = MIN (limit_x, cols);
866 rows = MIN (limit_y, rows);
867
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));
873
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);
886 }
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);
902 }
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);
913 }
914 } else {
915 if (doit)
916 sheet_cell_remove (cell->base.sheet, cell, TRUE, TRUE);
917 else
918 res = g_strdup (_("(empty)"));
919 }
920
921 return res;
922 }
923
924 static void
afc_set_cell(AutoFiller * af,GnmCell * cell,int n)925 afc_set_cell (AutoFiller *af, GnmCell *cell, int n)
926 {
927 afc_set_cell_hint (af, cell, &cell->pos, n, TRUE);
928 }
929
930 static char *
afc_hint(AutoFiller * af,GnmCellPos * pos,int n)931 afc_hint (AutoFiller *af, GnmCellPos *pos, int n)
932 {
933 return afc_set_cell_hint (af, NULL, pos, n, FALSE);
934 }
935
936 static AutoFiller *
auto_filler_copy(int size,guint last_col,guint last_row)937 auto_filler_copy (int size, guint last_col, guint last_row)
938 {
939 AutoFillerCopy *res = g_new (AutoFillerCopy, 1);
940
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);
951
952 return &res->filler;
953 }
954
955 /* ------------------------------------------------------------------------- */
956
957 static int
calc_steps(const GnmRange * r,int col_inc,int row_inc)958 calc_steps (const GnmRange *r, int col_inc, int row_inc)
959 {
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;
966 }
967
968
969 /*
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.
975 */
976
977 static char *
sheet_autofill_dir(Sheet * sheet,gboolean singleton,int base_col,int base_row,int region_size,int count_max,int col_inc,int row_inc,int last_col,int last_row,gboolean doit)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)
985 {
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;
995
996 if (count_max <= 0 || region_size <= 0)
997 return NULL;
998
999 /*
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.
1003 *
1004 * The allocations may be larger than we need, but we don't know
1005 * the right size yet.
1006 */
1007 styles = doit ? g_new0 (GnmStyle const *, region_size) : NULL;
1008 merges = g_new0 (GnmRange const *, region_size);
1009
1010 /*
1011 * i counts rows/cols.
1012 * j follows, but skips hidden parts of merged cells.
1013 */
1014
1015 /*
1016 * Pass 1: Have a look at the merges. We always go right or down
1017 * in this pass.
1018 */
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;
1029
1030 if (styles) {
1031 styles[j2] = sheet_style_get (sheet, col2, row2);
1032 gnm_style_ref (styles[j2]);
1033 }
1034
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++;
1042 }
1043 true_region_size = j;
1044
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));
1057 }
1058
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));
1071
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));
1084
1085 /*
1086 * Pass 2: Present all cells to the fillers and remove fillers that
1087 * cannot handle the contents.
1088 */
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;
1095
1096 if (reverse && merges[j]) {
1097 col -= range_width (merges[j]) - 1;
1098 row -= range_height (merges[j]) - 1;
1099 }
1100 cell = sheet_cell_get (sheet, col, row);
1101
1102 while (f) {
1103 AutoFiller *af = f->data;
1104 GList *next = f->next;
1105
1106 af->teach_cell (af, cell, j);
1107
1108 if (af->status == AFS_ERROR) {
1109 fillers = g_list_delete_link (fillers, f);
1110 af->finalize (af);
1111 }
1112
1113 f = next;
1114 }
1115
1116 i += (ms + 1);
1117 }
1118
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;
1125 }
1126 }
1127
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;
1137
1138 if (reverse && merges[k]) {
1139 col -= range_width (merges[k]) - 1;
1140 row -= range_height (merges[k]) - 1;
1141 }
1142 cell = sheet_cell_fetch (sheet, col, row);
1143 af->set_cell (af, cell, j);
1144
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);
1154 }
1155 i += (ms + 1);
1156 j++;
1157 }
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++;
1169 }
1170
1171 hint = af->hint (af, &pos, repeats * true_region_size + j - 1);
1172 }
1173
1174 while (fillers) {
1175 AutoFiller *af = fillers->data;
1176 fillers = g_list_delete_link (fillers, fillers);
1177 af->finalize (af);
1178 }
1179
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);
1186 }
1187
1188 g_free (merges);
1189 g_free (merge_size);
1190
1191 return hint;
1192 }
1193
1194 static void
add_item(GString * dst,char * item,char const * sep)1195 add_item (GString *dst, char *item, char const *sep)
1196 {
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, "?");
1205 }
1206
1207 static GString *
sheet_autofill_internal(Sheet * sheet,gboolean singleton,int base_col,int base_row,int w,int h,int end_col,int end_row,gboolean doit)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)
1213 {
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;
1220
1221 g_return_val_if_fail (IS_SHEET (sheet), NULL);
1222
1223 if (!doit)
1224 res = g_string_new (NULL);
1225
1226 pos.col = base_col;
1227 pos.row = base_row;
1228
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");
1241
1242 pos.row = base_row - series;
1243 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1244 series += mr ? range_height (mr) : 1;
1245 }
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 " | ");
1257
1258 pos.col = base_col - series;
1259 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1260 series += mr ? range_width (mr) : 1;
1261 }
1262 }
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");
1275
1276 pos.row = base_row + series;
1277 mr = gnm_sheet_merge_contains_pos (sheet, &pos);
1278 series += mr ? range_height (mr) : 1;
1279 }
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;
1294 }
1295 }
1296 }
1297
1298 return res;
1299 }
1300
1301
1302
1303 /**
1304 * gnm_autofill_fill:
1305 *
1306 * An internal routine to autofill a region. It does NOT
1307 * queue a recalc, flag a status update, or regen spans.
1308 */
1309 void
gnm_autofill_fill(Sheet * sheet,gboolean singleton,int base_col,int base_row,int w,int h,int end_col,int end_row)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)
1314 {
1315 sheet_autofill_internal (sheet, singleton,
1316 base_col, base_row,
1317 w, h,
1318 end_col, end_row,
1319 TRUE);
1320 }
1321
1322 GString *
gnm_autofill_hint(Sheet * sheet,gboolean default_increment,int base_col,int base_row,int w,int h,int end_col,int end_row)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)
1327 {
1328 return sheet_autofill_internal (sheet, default_increment,
1329 base_col, base_row,
1330 w, h,
1331 end_col, end_row,
1332 FALSE);
1333 }
1334