1.12.42
[gnumeric.git] / src / tools / dao.c
blob8b5963c0bc97fb685d55b8ab8f0764dea46420bd
2 /*
3 * dao.c:
5 * Authors:
6 * Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
7 * Andreas J. Guelzow <aguelzow@taliesin.ca>
9 * (C) Copyright 2000, 2001 by Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
10 * (C) Copyright 2001, 2002 by Andreas J. Guelzow <aguelzow@taliesin.ca>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses/>.
26 #include <gnumeric-config.h>
27 #include <tools/dao.h>
29 #include <expr.h>
30 #include <value.h>
31 #include <cell.h>
32 #include <sheet.h>
33 #include <ranges.h>
34 #include <style.h>
35 #include <sheet-style.h>
36 #include <workbook.h>
37 #include <workbook-view.h>
38 #include <workbook-control.h>
39 #include <command-context.h>
40 #include <gnm-format.h>
41 #include <sheet-merge.h>
42 #include <sheet-object-cell-comment.h>
43 #include <style-color.h>
44 #include <style-border.h>
45 #include <graph.h>
46 #include <goffice/goffice.h>
48 #include <glib.h>
49 #include <glib/gi18n-lib.h>
50 #include <string.h>
51 #include <time.h>
52 #include <parse-util.h>
54 /**
55 * dao_init: (skip)
56 * @dao:
57 * @type:
59 * Initialize dao to given type.
61 **/
63 data_analysis_output_t *
64 dao_init (data_analysis_output_t *dao,
65 data_analysis_output_type_t type)
67 if (dao == NULL) {
68 dao = g_new (data_analysis_output_t, 1);
69 dao->use_gfree = TRUE;
70 } else
71 dao->use_gfree = FALSE;
73 dao->type = type;
74 dao->start_col = 0;
75 dao->start_row = 0;
76 dao->offset_col = 0;
77 dao->offset_row = 0;
78 dao->cols = 1; /* Fixed in dao_prepare_output */
79 dao->rows = 1;
80 dao->sheet = NULL;
81 dao->autofit_flag = TRUE;
82 dao->autofit_noshrink = TRUE;
83 dao->clear_outputrange = TRUE;
84 dao->retain_format = FALSE;
85 dao->retain_comments = FALSE;
86 dao->put_formulas = FALSE;
87 dao->wbc = NULL;
88 dao->sos = NULL;
89 dao->omit_so = FALSE;
91 return dao;
94 /**
95 * dao_init_new_sheet: (skip)
96 * @dao:
98 **/
99 data_analysis_output_t *
100 dao_init_new_sheet (data_analysis_output_t *dao)
102 return dao_init (dao, NewSheetOutput);
105 void dao_free (data_analysis_output_t *dao)
107 g_slist_free_full (dao->sos, g_object_unref);
108 dao->sos = NULL;
110 if (dao->use_gfree)
111 g_free (dao);
115 * dao_load_from_value: (skip)
116 * @dao:
117 * @output_range:
120 data_analysis_output_t *
121 dao_load_from_value (data_analysis_output_t *dao,
122 GnmValue *output_range)
124 g_return_val_if_fail (output_range != NULL, dao);
125 g_return_val_if_fail (VALUE_IS_CELLRANGE (output_range), dao);
127 dao->start_col = output_range->v_range.cell.a.col;
128 dao->start_row = output_range->v_range.cell.a.row;
129 dao->cols = output_range->v_range.cell.b.col
130 - output_range->v_range.cell.a.col + 1;
131 dao->rows = output_range->v_range.cell.b.row
132 - output_range->v_range.cell.a.row + 1;
133 dao->sheet = output_range->v_range.cell.a.sheet;
135 return dao;
139 * dao_range_name:
140 * @dao:
142 * Provides the name of the output range
143 * The caller has to dispose of the name
147 static char *
148 dao_range_name (data_analysis_output_t *dao)
150 GnmRange range;
151 range_init (&range, dao->start_col, dao->start_row,
152 dao->start_col + dao->cols - 1,
153 dao->start_row + dao->rows - 1);
155 return undo_range_name (dao->sheet, &range);
159 * dao_command_descriptor:
160 * @dao:
161 * @format:
162 * @result:
164 * Uses format to provide a string to be used as command descriptor for
165 * undo/redo
169 char *
170 dao_command_descriptor (data_analysis_output_t *dao, char const *format,
171 gpointer result)
173 char *rangename = NULL;
174 char **text = result;
176 g_return_val_if_fail (result != NULL, NULL);
178 g_free (*text);
179 switch (dao->type) {
180 case NewSheetOutput:
181 *text = g_strdup_printf (format, _("New Sheet"));
182 break;
183 case NewWorkbookOutput:
184 *text = g_strdup_printf (format, _("New Workbook"));
185 break;
186 case RangeOutput:
187 default:
188 rangename = dao_range_name (dao);
189 *text = g_strdup_printf (format, rangename);
190 g_free (rangename);
191 break;
193 return *text;
197 * dao_adjust:
198 * @dao:
199 * @cols:
200 * @rows:
202 * shrinks the dao to the given cols/rows
203 * (or enlarges it if dao was a singleton)
207 void
208 dao_adjust (data_analysis_output_t *dao, gint cols, gint rows)
210 int max_rows, max_cols;
212 if (dao->cols == 1 && dao->rows == 1) {
213 if (cols != -1)
214 dao->cols = cols;
215 if (rows != -1)
216 dao->rows = rows;
217 } else {
218 if (cols != -1)
219 dao->cols = MIN (cols, dao->cols);
220 if (rows != -1)
221 dao->rows = MIN (rows, dao->rows);
224 if (dao->sheet) {
225 max_rows = gnm_sheet_get_max_rows (dao->sheet) - dao->start_row;
226 max_cols = gnm_sheet_get_max_cols (dao->sheet) - dao->start_col;
227 } else {
228 /* In case of NewSheetOutput and NewWorkbookOutput */
229 /* this is called before we actually create the */
230 /* new sheet and/or workbook */
231 Sheet *old_sheet = wb_control_cur_sheet (dao->wbc);
232 max_rows = gnm_sheet_get_max_rows (old_sheet) - dao->start_row;
233 max_cols = gnm_sheet_get_max_cols (old_sheet) - dao->start_col;
236 if (dao->cols > max_cols)
237 dao->cols = max_cols;
238 if (dao->rows > max_rows)
239 dao->rows = max_rows;
243 * dao_prepare_output:
244 * @dao:
245 * @name:
247 * prepares the output by creating a new sheet or workbook as appropriate
251 void
252 dao_prepare_output (WorkbookControl *wbc, data_analysis_output_t *dao,
253 const char *name)
255 char *unique_name;
257 if (wbc)
258 dao->wbc = wbc;
260 if (dao->type == NewSheetOutput) {
261 Sheet *old_sheet = dao->wbc
262 ? wb_control_cur_sheet (dao->wbc)
263 : dao->sheet;
264 Workbook *wb = old_sheet->workbook;
265 char *name_with_counter = g_strdup_printf ("%s (1)", name);
266 unique_name = workbook_sheet_get_free_name
267 (wb, name_with_counter, FALSE, TRUE);
268 g_free (name_with_counter);
269 dao->rows = gnm_sheet_get_max_rows (old_sheet);
270 dao->cols = gnm_sheet_get_max_cols (old_sheet);
271 dao->sheet = sheet_new (wb, unique_name, dao->cols, dao->rows);
272 g_free (unique_name);
273 dao->start_col = dao->start_row = 0;
274 workbook_sheet_attach (wb, dao->sheet);
275 } else if (dao->type == NewWorkbookOutput) {
276 Sheet *old_sheet = wb_control_cur_sheet (dao->wbc);
277 Workbook *wb = workbook_new ();
278 dao->rows = gnm_sheet_get_max_rows (old_sheet);
279 dao->cols = gnm_sheet_get_max_cols (old_sheet);
280 dao->sheet = sheet_new (wb, name, dao->cols, dao->rows);
281 dao->start_col = dao->start_row = 0;
282 workbook_sheet_attach (wb, dao->sheet);
283 dao->wbc = workbook_control_new_wrapper (dao->wbc, NULL, wb, NULL);
286 if (dao->wbc)
287 wb_view_sheet_focus (wb_control_view (dao->wbc), dao->sheet);
289 if (dao->rows == 0 || (dao->rows == 1 && dao->cols == 1))
290 dao->rows = gnm_sheet_get_max_rows (dao->sheet) - dao->start_row;
291 if (dao->cols == 0 || (dao->rows == 1 && dao->cols == 1))
292 dao->cols = gnm_sheet_get_max_cols (dao->sheet) - dao->start_col;
293 dao->offset_col = 0;
294 dao->offset_row = 0;
298 * dao_format_output:
299 * @dao:
300 * @cmd:
302 * format's the output range according to the settings
306 gboolean
307 dao_format_output (data_analysis_output_t *dao, char const *cmd)
309 int clear_flags = 0;
310 GnmRange range;
312 range_init (&range, dao->start_col, dao->start_row,
313 dao->start_col + dao->cols - 1,
314 dao->start_row + dao->rows - 1);
316 if (dao->type == RangeOutput
317 && sheet_range_splits_region (dao->sheet, &range, NULL,
318 GO_CMD_CONTEXT (dao->wbc), cmd))
319 return TRUE;
321 if (dao->clear_outputrange)
322 clear_flags = CLEAR_VALUES | CLEAR_RECALC_DEPS;
323 if (!dao->retain_format)
324 clear_flags |= CLEAR_FORMATS;
325 if (!dao->retain_comments)
326 clear_flags |= CLEAR_COMMENTS;
328 sheet_clear_region (dao->sheet,
329 range.start.col, range.start.row,
330 range.end.col, range.end.row,
331 clear_flags | CLEAR_NOCHECKARRAY | CLEAR_MERGES,
332 GO_CMD_CONTEXT (dao->wbc));
333 return FALSE;
337 static gboolean
338 adjust_range (data_analysis_output_t *dao, GnmRange *r)
340 range_normalize (r);
342 r->start.col += dao->offset_col + dao->start_col;
343 r->end.col += dao->offset_col + dao->start_col;
344 r->start.row += dao->offset_row + dao->start_row;
345 r->end.row += dao->offset_row + dao->start_row;
347 if (dao->type == RangeOutput && (dao->cols > 1 || dao->rows > 1)) {
348 if (r->end.col >= dao->start_col + dao->cols)
349 r->end.col = dao->start_col + dao->cols - 1;
350 if (r->end.row >= dao->start_row + dao->rows)
351 r->end.row = dao->start_row + dao->rows - 1;
354 range_ensure_sanity (r, dao->sheet);
356 return ((r->start.col <= r->end.col) && (r->start.row <= r->end.row));
360 gboolean
361 dao_cell_is_visible (data_analysis_output_t *dao, int col, int row)
363 col += dao->offset_col;
364 row += dao->offset_row;
366 if (dao->type == RangeOutput &&
367 (dao->cols > 1 || dao->rows > 1) &&
368 (col >= dao->cols || row >= dao->rows))
369 return FALSE;
371 col += dao->start_col;
372 row += dao->start_row;
374 return (!(col >= gnm_sheet_get_max_cols (dao->sheet) || row >= gnm_sheet_get_max_rows (dao->sheet)));
379 * dao_set_array_expr: (skip)
380 * @dao:
381 * @col: starting column
382 * @row: starting row
383 * @cols: number of columns
384 * @rows: number of rows
385 * @expr: (transfer full): expression to set
388 void
389 dao_set_array_expr (data_analysis_output_t *dao,
390 int col, int row, int cols, int rows,
391 GnmExpr const *expr)
393 GnmExprTop const *texpr;
394 GnmRange r;
396 range_init (&r, col, row, col + cols - 1, row + rows -1);
398 if (!adjust_range (dao, &r)) {
399 gnm_expr_free (expr);
400 return;
403 texpr = gnm_expr_top_new (expr);
404 gnm_cell_set_array_formula (dao->sheet,
405 r.start.col, r.start.row,
406 r.end.col, r.end.row,
407 texpr);
411 * dao_set_cell_array_expr: (skip)
412 * @dao:
413 * @col: column
414 * @row: row
415 * @expr: (transfer full): expression to set
417 * Sets a singleton array expression.
419 void
420 dao_set_cell_array_expr (data_analysis_output_t *dao, int col, int row,
421 GnmExpr const *expr)
423 dao_set_array_expr (dao, col, row, 1, 1, expr);
427 * dao_set_cell_expr: (skip)
428 * @dao:
429 * @col: column
430 * @row: row
431 * @expr: (transfer full): expression to set
433 * Sets a singleton array expression.
435 void
436 dao_set_cell_expr (data_analysis_output_t *dao, int col, int row,
437 GnmExpr const *expr)
439 GnmCell *cell;
440 GnmExprTop const *texpr;
441 GnmRange r;
443 range_init (&r, col, row, col, row);
445 if (!adjust_range (dao, &r)) {
446 gnm_expr_free (expr);
447 return;
450 cell = sheet_cell_fetch (dao->sheet, r.start.col, r.start.row);
451 texpr = gnm_expr_top_new (expr);
452 gnm_cell_set_expr (cell, texpr);
453 gnm_expr_top_unref (texpr);
458 * dao_set_cell_value:
459 * @dao:
460 * @col:
461 * @row:
462 * @v: (transfer full):
464 * set cell to a value
466 * Note: the rows/cols specification for all dao_set_cell_...
467 * commands are relative to the location of the output
469 void
470 dao_set_cell_value (data_analysis_output_t *dao, int col, int row, GnmValue *v)
472 GnmCell *cell;
473 GnmRange r;
475 range_init (&r, col, row, col, row);
477 if (!adjust_range (dao, &r)) {
478 value_release (v);
479 return;
482 cell = sheet_cell_fetch (dao->sheet, r.start.col, r.start.row);
484 sheet_cell_set_value (cell, v);
488 * dao_set_cell:
489 * @dao:
490 * @col:
491 * @row:
492 * @text:
494 * set cell to a string
498 void
499 dao_set_cell (data_analysis_output_t *dao, int col, int row, const char *text)
501 if (text == NULL) {
502 /* FIXME: should we erase instead? */
503 dao_set_cell_value (dao, col, row, value_new_empty ());
504 } else {
505 dao_set_cell_value (dao, col, row, value_new_string (text));
511 * dao_set_cell_printf:
512 * @dao:
513 * @col:
514 * @row:
515 * @fmt:
516 * @...:
518 * create format string and set cell.
521 void
522 dao_set_cell_printf (data_analysis_output_t *dao, int col, int row,
523 const char *fmt, ...)
525 char *buffer;
526 va_list args;
528 va_start (args, fmt);
529 buffer = g_strdup_vprintf (fmt, args);
530 va_end (args);
532 dao_set_cell_value (dao, col, row, value_new_string (buffer));
533 g_free (buffer);
538 * set_cell_float:
539 * @dao:
540 * @col:
541 * @row:
542 * @v:
544 * set cell to a gnm_float
548 void
549 dao_set_cell_float (data_analysis_output_t *dao, int col, int row, gnm_float v)
551 dao_set_cell_value (dao, col, row, value_new_float (v));
556 * set_cell_int:
557 * @dao:
558 * @col:
559 * @row:
560 * @v:
562 * set cell to an int
566 void
567 dao_set_cell_int (data_analysis_output_t *dao, int col, int row, int v)
569 dao_set_cell_value (dao, col, row, value_new_int (v));
574 * dao_set_cell_na:
575 * @dao:
576 * @col:
577 * @row:
579 * set cell to NA
583 void
584 dao_set_cell_na (data_analysis_output_t *dao, int col, int row)
586 dao_set_cell_value (dao, col, row, value_new_error_NA (NULL));
590 * dao_set_cell_float_na:
591 * @dao:
592 * @col:
593 * @row:
594 * @v:
595 * @is_valid:
597 * set cell to a gnm_float or NA as appropraite
601 void
602 dao_set_cell_float_na (data_analysis_output_t *dao, int col, int row,
603 gnm_float v, gboolean is_valid)
605 if (is_valid) {
606 dao_set_cell_float (dao, col, row, v);
607 } else {
608 dao_set_cell_na (dao, col, row);
613 * dao_set_cell_comment:
614 * @dao:
615 * @col:
616 * @row:
617 * @comment:
619 * set a cell comment
622 void
623 dao_set_cell_comment (data_analysis_output_t *dao, int col, int row,
624 const char *comment)
626 char const *author = NULL;
627 GnmRange r;
629 range_init (&r, col, row, col, row);
631 if (adjust_range (dao, &r))
632 cell_set_comment (dao->sheet, &r.start, author, comment, NULL);
637 * dao_autofit_these_columns:
638 * @dao:
639 * @from_col:
640 * @to_col:
642 * Fits the specified columns to their content
644 void
645 dao_autofit_these_columns (data_analysis_output_t *dao, int from_col, int to_col)
647 GnmRange r;
649 if (!dao->autofit_flag)
650 return;
652 range_init_cols (&r, dao->sheet,
653 from_col + dao->start_col,
654 to_col + dao->start_col);
656 colrow_autofit (dao->sheet, &r, TRUE,
657 FALSE, dao->autofit_noshrink, FALSE,
658 NULL, NULL);
662 * dao_autofit_columns:
663 * @dao:
665 * fits all columns to their content
667 void
668 dao_autofit_columns (data_analysis_output_t *dao)
670 dao_autofit_these_columns (dao, 0, dao->cols - 1);
673 void
674 dao_autofit_these_rows (data_analysis_output_t *dao, int from_row, int to_row)
676 GnmRange r;
678 if (!dao->autofit_flag)
679 return;
681 range_init_rows (&r, dao->sheet,
682 from_row + dao->start_row,
683 to_row + dao->start_row);
685 colrow_autofit (dao->sheet, &r, FALSE,
686 FALSE, dao->autofit_noshrink, FALSE,
687 NULL, NULL);
690 void
691 dao_autofit_rows (data_analysis_output_t *dao)
693 dao_autofit_these_rows (dao, 0, dao->rows - 1);
698 * dao_set_style:
699 * @dao:
700 * @col1:
701 * @row1:
702 * @col2:
703 * @row2:
704 * @style: (transfer full):
706 * Applies a partial style to the given region.
709 static void
710 dao_set_style (data_analysis_output_t *dao, int col1, int row1,
711 int col2, int row2, GnmStyle *mstyle)
713 GnmRange r;
715 range_init (&r, col1, row1, col2, row2);
717 if (!adjust_range (dao, &r)) {
718 gnm_style_unref (mstyle);
719 return;
722 sheet_style_apply_range (dao->sheet, &r, mstyle);
726 * dao_set_bold:
727 * @dao:
728 * @col1:
729 * @row1:
730 * @col2:
731 * @row2:
733 * sets the given cell range to bold
737 void
738 dao_set_bold (data_analysis_output_t *dao, int col1, int row1,
739 int col2, int row2)
741 GnmStyle *mstyle = gnm_style_new ();
743 gnm_style_set_font_bold (mstyle, TRUE);
745 dao_set_style (dao, col1, row1, col2, row2, mstyle);
749 * dao_set_italic:
750 * @dao:
751 * @col1:
752 * @row1:
753 * @col2:
754 * @row2:
756 * sets the given cell range to italic
760 void
761 dao_set_italic (data_analysis_output_t *dao, int col1, int row1,
762 int col2, int row2)
764 GnmStyle *mstyle = gnm_style_new ();
766 gnm_style_set_font_italic (mstyle, TRUE);
767 dao_set_style (dao, col1, row1, col2, row2, mstyle);
771 * dao_set_percent:
772 * @dao:
773 * @col1:
774 * @row1:
775 * @col2:
776 * @row2:
778 * set the given cell range to percent format
782 void
783 dao_set_percent (data_analysis_output_t *dao, int col1, int row1,
784 int col2, int row2)
786 GnmStyle *mstyle = gnm_style_new ();
787 gnm_style_set_format (mstyle, go_format_default_percentage ());
788 dao_set_style (dao, col1, row1, col2, row2, mstyle);
792 * dao_set_date:
793 * @dao:
794 * @col1:
795 * @row1:
796 * @col2:
797 * @row2:
799 * set the given cell range to date format
803 void
804 dao_set_date (data_analysis_output_t *dao, int col1, int row1,
805 int col2, int row2)
807 GnmStyle *mstyle = gnm_style_new ();
808 gnm_style_set_format (mstyle, go_format_default_date ());
809 dao_set_style (dao, col1, row1, col2, row2, mstyle);
813 * dao_set_format:
814 * @dao:
815 * @col1:
816 * @row1:
817 * @col2:
818 * @row2:
819 * @format:
821 * set the given cell range to given format
825 void
826 dao_set_format (data_analysis_output_t *dao, int col1, int row1,
827 int col2, int row2,
828 char const * format)
830 GOFormat *fmt;
832 fmt = go_format_new_from_XL (format);
833 if (go_format_is_invalid (fmt)) {
834 g_warning ("Ignoring invalid format [%s]", format);
835 } else {
836 GnmStyle *mstyle = gnm_style_new ();
837 gnm_style_set_format (mstyle, fmt);
838 dao_set_style (dao, col1, row1, col2, row2, mstyle);
840 go_format_unref (fmt);
845 * dao_set_colors:
846 * @dao:
847 * @col1:
848 * @row1:
849 * @col2:
850 * @row2:
852 * set the given cell range to given background and text colors
856 void
857 dao_set_colors (data_analysis_output_t *dao, int col1, int row1,
858 int col2, int row2,
859 GnmColor *fore, GnmColor *back)
861 GnmStyle *mstyle;
863 mstyle = gnm_style_new ();
864 if (fore)
865 gnm_style_set_font_color (mstyle, fore);
866 if (back) {
867 gnm_style_set_back_color (mstyle, back);
868 gnm_style_set_pattern (mstyle, 1);
870 dao_set_style (dao, col1, row1, col2, row2, mstyle);
874 * dao_set_align:
875 * @dao:
876 * @col1:
877 * @row1:
878 * @col2:
879 * @row2:
881 * set the given horizontal and vertical alignment to a cell range
885 void
886 dao_set_align (data_analysis_output_t *dao, int col1, int row1,
887 int col2, int row2,
888 GnmHAlign align_h, GnmVAlign align_v)
890 GnmStyle *mstyle;
892 mstyle = gnm_style_new ();
893 gnm_style_set_align_h (mstyle, align_h);
894 gnm_style_set_align_v (mstyle, align_v);
895 dao_set_style (dao, col1, row1, col2, row2, mstyle);
899 * dao_set_border:
900 * @dao:
901 * @col1:
902 * @row1:
903 * @col2:
904 * @row2:
909 void
910 dao_set_border (data_analysis_output_t *dao, int col1, int row1,
911 int col2, int row2,
912 GnmStyleElement elem, GnmStyleBorderType border,
913 GnmColor *color,
914 GnmStyleBorderOrientation orientation)
916 GnmStyle *mstyle;
918 mstyle = gnm_style_new ();
919 gnm_style_set_border (mstyle, elem,
920 gnm_style_border_fetch (border,
921 color,
922 orientation));
923 dao_set_style (dao, col1, row1, col2, row2, mstyle);
929 * dao_get_colrow_state_list:
930 * @dao:
931 * @is_cols: %TRUE for columns, %FALSE for rows.
934 * Returns: (transfer full):
936 ColRowStateList *
937 dao_get_colrow_state_list (data_analysis_output_t *dao, gboolean is_cols)
939 switch (dao->type) {
940 case NewSheetOutput:
941 case NewWorkbookOutput:
942 return NULL;
943 case RangeOutput:
944 if (is_cols)
945 return colrow_get_states
946 (dao->sheet, is_cols, dao->start_col,
947 dao->start_col + dao->cols - 1);
948 else
949 return colrow_get_states
950 (dao->sheet, is_cols, dao->start_row,
951 dao->start_row + dao->rows - 1);
952 default:
953 return NULL;
958 * dao_set_colrow_state_list:
959 * @dao:
960 * @is_cols: %TRUE for columns, %FALSE for rows.
961 * @list:
964 void
965 dao_set_colrow_state_list (data_analysis_output_t *dao, gboolean is_cols,
966 ColRowStateList *list)
968 g_return_if_fail (list);
970 if (dao->type == RangeOutput)
971 colrow_set_states (dao->sheet, is_cols,
972 is_cols ? dao->start_col : dao->start_row,
973 list);
976 void
977 dao_append_date (GString *buf)
979 GDate date;
980 struct tm tm_s;
981 gchar *tmp;
982 time_t now;
984 now = time (NULL);
985 g_date_set_time_t (&date, now);
986 g_date_to_struct_tm (&date, &tm_s);
987 tm_s.tm_sec = now % 60;
988 tm_s.tm_min = (now / 60) % 60;
989 tm_s.tm_hour = (now / 3600) % 24;
990 tmp = asctime (&tm_s);
991 g_string_append (buf, tmp);
995 * dao_write_header:
996 * @dao:
997 * @toolname: name of the tool, like Solver or Risk simulation
998 * @title:
999 * @sheet:
1001 * Writes the titles of a report.
1004 void
1005 dao_write_header (data_analysis_output_t *dao, const gchar *toolname,
1006 const gchar *title, Sheet *sheet)
1008 GString *buf;
1009 const char *uri;
1011 buf = g_string_new (NULL);
1012 g_string_append_printf (buf, "%s %s %s %s",
1013 _("Gnumeric "), toolname, VERSION, title);
1014 dao_set_cell (dao, 0, 0, buf->str);
1015 g_string_free (buf, FALSE);
1017 buf = g_string_new (NULL);
1018 uri = go_doc_get_uri (GO_DOC (sheet->workbook));
1019 g_string_append_printf (buf, "%s [%s]%s", _("Worksheet:"),
1020 uri,
1021 sheet->name_quoted);
1022 dao_set_cell (dao, 0, 1, buf->str);
1023 g_string_free (buf, FALSE);
1025 buf = g_string_new (NULL);
1026 g_string_append (buf, _("Report Created: "));
1027 dao_append_date (buf);
1028 dao_set_cell (dao, 0, 2, buf->str);
1029 g_string_free (buf, FALSE);
1031 dao_set_bold (dao, 0, 0, 0, 2);
1035 char *
1036 dao_find_name (Sheet *sheet, int col, int row)
1038 static char *str = NULL;
1039 const char *col_str = "";
1040 const char *row_str = "";
1041 int col_n, row_n;
1043 for (col_n = col - 1; col_n >= 0; col_n--) {
1044 GnmCell *cell = sheet_cell_get (sheet, col_n, row);
1045 if (cell && !VALUE_IS_NUMBER (cell->value)) {
1046 col_str = value_peek_string (cell->value);
1047 break;
1051 for (row_n = row - 1; row_n >= 0; row_n--) {
1052 GnmCell *cell = sheet_cell_get (sheet, col, row_n);
1053 if (cell && !VALUE_IS_NUMBER (cell->value)) {
1054 row_str = value_peek_string (cell->value);
1055 break;
1059 if (*col_str || *row_str) {
1060 str = g_new (char, strlen (col_str) + strlen (row_str) + 2);
1062 if (*col_str)
1063 sprintf (str, "%s %s", col_str, row_str);
1064 else
1065 sprintf (str, "%s", row_str);
1066 } else {
1067 const char *tmp = cell_coord_name (col, row);
1069 str = g_new (char, strlen (tmp) + 1);
1070 strcpy (str, tmp);
1073 return str;
1076 gboolean
1077 dao_put_formulas (data_analysis_output_t *dao)
1079 g_return_val_if_fail (dao != NULL, FALSE);
1080 return dao->put_formulas;
1083 static GnmValue *
1084 cb_convert_to_value (GnmCellIter const *iter, G_GNUC_UNUSED gpointer user)
1086 GnmCell *cell = iter->cell;
1087 if (!cell || !gnm_cell_has_expr (cell))
1088 return NULL;
1090 gnm_cell_eval (cell);
1092 if (gnm_expr_top_is_array_elem (cell->base.texpr, NULL, NULL))
1093 return NULL;
1095 gnm_cell_convert_expr_to_value (cell);
1096 return NULL;
1100 static void
1101 dao_convert_to_values (data_analysis_output_t *dao)
1103 if (dao->put_formulas)
1104 return;
1106 sheet_foreach_cell_in_region (dao->sheet, CELL_ITER_IGNORE_BLANK,
1107 dao->start_col, dao->start_row,
1108 dao->start_col + dao->cols - 1,
1109 dao->start_row + dao->rows - 1,
1110 cb_convert_to_value,
1111 NULL);
1114 void
1115 dao_redraw_respan (data_analysis_output_t *dao)
1117 GnmRange r;
1119 range_init (&r, dao->start_col, dao->start_row,
1120 dao->start_col + dao->cols - 1,
1121 dao->start_row + dao->rows - 1);
1122 sheet_range_calc_spans (dao->sheet, &r,
1123 GNM_SPANCALC_RESIZE | GNM_SPANCALC_RE_RENDER);
1124 sheet_region_queue_recalc (dao->sheet, &r);
1125 dao_convert_to_values (dao);
1126 sheet_redraw_range (dao->sheet, &r);
1130 static GnmExpr const *
1131 dao_get_cellref_full (data_analysis_output_t *dao, int x, int y, Sheet *sheet)
1133 GnmCellRef r;
1134 r.sheet = sheet;
1135 r.col = x + dao->start_col + dao->offset_col;
1136 r.col_relative = FALSE;
1137 r.row = y + dao->start_row + dao->offset_row;
1138 r.row_relative = FALSE;
1139 return gnm_expr_new_cellref (&r);
1142 GnmExpr const *
1143 dao_get_cellref (data_analysis_output_t *dao, int x, int y)
1145 return dao_get_cellref_full (dao, x, y, NULL);
1148 static GnmExpr const *
1149 dao_get_rangeref_full (data_analysis_output_t *dao, int ax, int ay, int bx, int by, Sheet *sheet)
1151 GnmValue *v;
1152 GnmCellRef ar;
1153 GnmCellRef br;
1155 ar.sheet = sheet;
1156 ar.col = ax + dao->start_col + dao->offset_col;
1157 ar.col_relative = FALSE;
1158 ar.row = ay + dao->start_row + dao->offset_row;
1159 ar.row_relative = FALSE;
1161 br.sheet = sheet;
1162 br.col = bx + dao->start_col + dao->offset_col;
1163 br.col_relative = FALSE;
1164 br.row = by + dao->start_row + dao->offset_row;
1165 br.row_relative = FALSE;
1167 v = value_new_cellrange (&ar, &br, 0, 0);
1168 return gnm_expr_new_constant (v);
1171 GnmExpr const *
1172 dao_get_rangeref (data_analysis_output_t *dao, int ax, int ay, int bx, int by)
1174 return dao_get_rangeref_full (dao, ax, ay, bx, by, NULL);
1177 void
1178 dao_set_sheet_object (data_analysis_output_t *dao, int col, int row, SheetObject* so)
1180 SheetObjectAnchor anchor;
1181 GnmRange anchor_r;
1183 g_return_if_fail (so != NULL);
1185 if (dao->omit_so) {
1186 g_object_unref (so);
1187 return;
1190 range_init (&anchor_r, dao->start_col + col, dao->start_row + row,
1191 dao->start_col + ((dao->cols < 5) ? dao->cols : 5),
1192 dao->start_row + ((dao->rows < 20) ? dao->rows : 20));
1194 sheet_object_anchor_init (&anchor, &anchor_r, NULL, GOD_ANCHOR_DIR_UNKNOWN,
1195 GNM_SO_ANCHOR_TWO_CELLS);
1196 sheet_object_set_anchor (so, &anchor);
1197 sheet_object_set_sheet (so, dao->sheet);
1199 dao->sos = g_slist_prepend (dao->sos, so);
1203 * dao_go_data_vector:
1204 * @dao:
1205 * @ax:
1206 * @ay:
1207 * @bx:
1208 * @by:
1210 * Returns: (transfer full):
1212 GOData *
1213 dao_go_data_vector (data_analysis_output_t *dao, int ax, int ay, int bx, int by)
1215 return gnm_go_data_vector_new_expr (dao->sheet, gnm_expr_top_new (dao_get_rangeref_full (dao, ax, ay, bx, by, dao->sheet)));
1219 * dao_surrender_so:
1220 * @dao:
1222 * Returns: (element-type GObject) (transfer full):
1224 GSList *
1225 dao_surrender_so (data_analysis_output_t *dao)
1227 GSList *l = dao->sos;
1228 dao->sos = NULL;
1230 return l;
1233 void
1234 dao_set_omit_so (data_analysis_output_t *dao, gboolean omit)
1236 dao->omit_so = omit;
1241 void
1242 dao_set_merge (data_analysis_output_t *dao, int col1, int row1,
1243 int col2, int row2)
1245 GnmRange r;
1247 range_init (&r, col1, row1, col2, row2);
1248 if (adjust_range (dao, &r))
1249 gnm_sheet_merge_add (dao->sheet, &r, TRUE, NULL);