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