Compilation: fix up tools includes.
[gnumeric.git] / src / tools / dao.c
blobffcd9fbd88973bc8fdbcbb68bd0c5d99d7b0d5a2
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /*
4 * dao.c:
6 * Authors:
7 * Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
8 * Andreas J. Guelzow <aguelzow@taliesin.ca>
10 * (C) Copyright 2000, 2001 by Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
11 * (C) Copyright 2001, 2002 by Andreas J. Guelzow <aguelzow@taliesin.ca>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses/>.
27 #include <gnumeric-config.h>
28 #include <tools/dao.h>
30 #include "expr.h"
31 #include "value.h"
32 #include "cell.h"
33 #include "sheet.h"
34 #include "ranges.h"
35 #include "style.h"
36 #include "sheet-style.h"
37 #include "workbook.h"
38 #include "workbook-view.h"
39 #include "workbook-control.h"
40 #include "command-context.h"
41 #include "gnm-format.h"
42 #include "sheet-merge.h"
43 #include "sheet-object-cell-comment.h"
44 #include "style-color.h"
45 #include "style-border.h"
46 #include "graph.h"
47 #include <goffice/goffice.h>
49 #include <glib.h>
50 #include <glib/gi18n-lib.h>
51 #include <string.h>
52 #include <time.h>
53 #include <parse-util.h>
55 /**
56 * dao_init: (skip)
57 * @dao:
58 * @type:
60 * Initialize dao to given type.
62 **/
64 data_analysis_output_t *
65 dao_init (data_analysis_output_t *dao,
66 data_analysis_output_type_t type)
68 if (dao == NULL) {
69 dao = g_new (data_analysis_output_t, 1);
70 dao->use_gfree = TRUE;
71 } else
72 dao->use_gfree = FALSE;
74 dao->type = type;
75 dao->start_col = 0;
76 dao->start_row = 0;
77 dao->offset_col = 0;
78 dao->offset_row = 0;
79 dao->cols = 1; /* Fixed in dao_prepare_output */
80 dao->rows = 1;
81 dao->sheet = NULL;
82 dao->autofit_flag = TRUE;
83 dao->autofit_noshrink = TRUE;
84 dao->clear_outputrange = TRUE;
85 dao->retain_format = FALSE;
86 dao->retain_comments = FALSE;
87 dao->put_formulas = FALSE;
88 dao->wbc = NULL;
89 dao->sos = NULL;
90 dao->omit_so = FALSE;
92 return dao;
95 /**
96 * dao_init_new_sheet: (skip)
97 * @dao:
99 **/
100 data_analysis_output_t *
101 dao_init_new_sheet (data_analysis_output_t *dao)
103 return dao_init (dao, NewSheetOutput);
106 void dao_free (data_analysis_output_t *dao)
108 g_slist_free_full (dao->sos, g_object_unref);
109 dao->sos = NULL;
111 if (dao->use_gfree)
112 g_free (dao);
116 * dao_load_from_value: (skip)
117 * @dao:
118 * @output_range:
121 data_analysis_output_t *
122 dao_load_from_value (data_analysis_output_t *dao,
123 GnmValue *output_range)
125 g_return_val_if_fail (output_range != NULL, dao);
126 g_return_val_if_fail (VALUE_IS_CELLRANGE (output_range), dao);
128 dao->start_col = output_range->v_range.cell.a.col;
129 dao->start_row = output_range->v_range.cell.a.row;
130 dao->cols = output_range->v_range.cell.b.col
131 - output_range->v_range.cell.a.col + 1;
132 dao->rows = output_range->v_range.cell.b.row
133 - output_range->v_range.cell.a.row + 1;
134 dao->sheet = output_range->v_range.cell.a.sheet;
136 return dao;
140 * dao_range_name:
141 * @dao:
143 * Provides the name of the output range
144 * The caller has to dispose of the name
148 static char *
149 dao_range_name (data_analysis_output_t *dao)
151 GnmRange range;
152 range_init (&range, dao->start_col, dao->start_row,
153 dao->start_col + dao->cols - 1,
154 dao->start_row + dao->rows - 1);
156 return undo_range_name (dao->sheet, &range);
160 * dao_command_descriptor:
161 * @dao:
162 * @format:
163 * @result:
165 * Uses format to provide a string to be used as command descriptor for
166 * undo/redo
170 char *
171 dao_command_descriptor (data_analysis_output_t *dao, char const *format,
172 gpointer result)
174 char *rangename = NULL;
175 char **text = result;
177 g_return_val_if_fail (result != NULL, NULL);
179 g_free (*text);
180 switch (dao->type) {
181 case NewSheetOutput:
182 *text = g_strdup_printf (format, _("New Sheet"));
183 break;
184 case NewWorkbookOutput:
185 *text = g_strdup_printf (format, _("New Workbook"));
186 break;
187 case RangeOutput:
188 default:
189 rangename = dao_range_name (dao);
190 *text = g_strdup_printf (format, rangename);
191 g_free (rangename);
192 break;
194 return *text;
198 * dao_adjust:
199 * @dao:
200 * @cols:
201 * @rows:
203 * shrinks the dao to the given cols/rows
204 * (or enlarges it if dao was a singleton)
208 void
209 dao_adjust (data_analysis_output_t *dao, gint cols, gint rows)
211 int max_rows, max_cols;
213 if (dao->cols == 1 && dao->rows == 1) {
214 if (cols != -1)
215 dao->cols = cols;
216 if (rows != -1)
217 dao->rows = rows;
218 } else {
219 if (cols != -1)
220 dao->cols = MIN (cols, dao->cols);
221 if (rows != -1)
222 dao->rows = MIN (rows, dao->rows);
225 if (dao->sheet) {
226 max_rows = gnm_sheet_get_max_rows (dao->sheet) - dao->start_row;
227 max_cols = gnm_sheet_get_max_cols (dao->sheet) - dao->start_col;
228 } else {
229 /* In case of NewSheetOutput and NewWorkbookOutput */
230 /* this is called before we actually create the */
231 /* new sheet and/or workbook */
232 Sheet *old_sheet = wb_control_cur_sheet (dao->wbc);
233 max_rows = gnm_sheet_get_max_rows (old_sheet) - dao->start_row;
234 max_cols = gnm_sheet_get_max_cols (old_sheet) - dao->start_col;
237 if (dao->cols > max_cols)
238 dao->cols = max_cols;
239 if (dao->rows > max_rows)
240 dao->rows = max_rows;
244 * dao_prepare_output:
245 * @dao:
246 * @name:
248 * prepares the output by creating a new sheet or workbook as appropriate
252 void
253 dao_prepare_output (WorkbookControl *wbc, data_analysis_output_t *dao,
254 const char *name)
256 char *unique_name;
258 if (wbc)
259 dao->wbc = wbc;
261 if (dao->type == NewSheetOutput) {
262 Sheet *old_sheet = dao->wbc
263 ? wb_control_cur_sheet (dao->wbc)
264 : dao->sheet;
265 Workbook *wb = old_sheet->workbook;
266 char *name_with_counter = g_strdup_printf ("%s (1)", name);
267 unique_name = workbook_sheet_get_free_name
268 (wb, name_with_counter, FALSE, TRUE);
269 g_free (name_with_counter);
270 dao->rows = gnm_sheet_get_max_rows (old_sheet);
271 dao->cols = gnm_sheet_get_max_cols (old_sheet);
272 dao->sheet = sheet_new (wb, unique_name, dao->cols, dao->rows);
273 g_free (unique_name);
274 dao->start_col = dao->start_row = 0;
275 workbook_sheet_attach (wb, dao->sheet);
276 } else if (dao->type == NewWorkbookOutput) {
277 Sheet *old_sheet = wb_control_cur_sheet (dao->wbc);
278 Workbook *wb = workbook_new ();
279 dao->rows = gnm_sheet_get_max_rows (old_sheet);
280 dao->cols = gnm_sheet_get_max_cols (old_sheet);
281 dao->sheet = sheet_new (wb, name, dao->cols, dao->rows);
282 dao->start_col = dao->start_row = 0;
283 workbook_sheet_attach (wb, dao->sheet);
284 dao->wbc = workbook_control_new_wrapper (dao->wbc, NULL, wb, NULL);
287 if (dao->wbc)
288 wb_view_sheet_focus (wb_control_view (dao->wbc), dao->sheet);
290 if (dao->rows == 0 || (dao->rows == 1 && dao->cols == 1))
291 dao->rows = gnm_sheet_get_max_rows (dao->sheet) - dao->start_row;
292 if (dao->cols == 0 || (dao->rows == 1 && dao->cols == 1))
293 dao->cols = gnm_sheet_get_max_cols (dao->sheet) - dao->start_col;
294 dao->offset_col = 0;
295 dao->offset_row = 0;
299 * dao_format_output:
300 * @dao:
301 * @cmd:
303 * format's the output range according to the settings
307 gboolean
308 dao_format_output (data_analysis_output_t *dao, char const *cmd)
310 int clear_flags = 0;
311 GnmRange range;
313 range_init (&range, dao->start_col, dao->start_row,
314 dao->start_col + dao->cols - 1,
315 dao->start_row + dao->rows - 1);
317 if (dao->type == RangeOutput
318 && sheet_range_splits_region (dao->sheet, &range, NULL,
319 GO_CMD_CONTEXT (dao->wbc), cmd))
320 return TRUE;
322 if (dao->clear_outputrange)
323 clear_flags = CLEAR_VALUES | CLEAR_RECALC_DEPS;
324 if (!dao->retain_format)
325 clear_flags |= CLEAR_FORMATS;
326 if (!dao->retain_comments)
327 clear_flags |= CLEAR_COMMENTS;
329 sheet_clear_region (dao->sheet,
330 range.start.col, range.start.row,
331 range.end.col, range.end.row,
332 clear_flags | CLEAR_NOCHECKARRAY | CLEAR_MERGES,
333 GO_CMD_CONTEXT (dao->wbc));
334 return FALSE;
338 static gboolean
339 adjust_range (data_analysis_output_t *dao, GnmRange *r)
341 range_normalize (r);
343 r->start.col += dao->offset_col + dao->start_col;
344 r->end.col += dao->offset_col + dao->start_col;
345 r->start.row += dao->offset_row + dao->start_row;
346 r->end.row += dao->offset_row + dao->start_row;
348 if (dao->type == RangeOutput && (dao->cols > 1 || dao->rows > 1)) {
349 if (r->end.col >= dao->start_col + dao->cols)
350 r->end.col = dao->start_col + dao->cols - 1;
351 if (r->end.row >= dao->start_row + dao->rows)
352 r->end.row = dao->start_row + dao->rows - 1;
355 range_ensure_sanity (r, dao->sheet);
357 return ((r->start.col <= r->end.col) && (r->start.row <= r->end.row));
361 gboolean
362 dao_cell_is_visible (data_analysis_output_t *dao, int col, int row)
364 col += dao->offset_col;
365 row += dao->offset_row;
367 if (dao->type == RangeOutput &&
368 (dao->cols > 1 || dao->rows > 1) &&
369 (col >= dao->cols || row >= dao->rows))
370 return FALSE;
372 col += dao->start_col;
373 row += dao->start_row;
375 return (!(col >= gnm_sheet_get_max_cols (dao->sheet) || row >= gnm_sheet_get_max_rows (dao->sheet)));
380 * dao_set_cell_array_expr absorbs the reference for the expr.
383 void
384 dao_set_array_expr (data_analysis_output_t *dao,
385 int col, int row, int cols, int rows,
386 GnmExpr const *expr)
388 GnmExprTop const *texpr;
389 GnmRange r;
391 range_init (&r, col, row, col + cols - 1, row + rows -1);
393 if (!adjust_range (dao, &r)) {
394 gnm_expr_free (expr);
395 return;
398 texpr = gnm_expr_top_new (expr);
399 gnm_cell_set_array_formula (dao->sheet,
400 r.start.col, r.start.row,
401 r.end.col, r.end.row,
402 texpr);
405 * dao_set_cell_array_expr absorbs the reference for the expr.
408 void
409 dao_set_cell_array_expr (data_analysis_output_t *dao, int col, int row,
410 GnmExpr const *expr)
412 dao_set_array_expr (dao, col, row, 1, 1, expr);
416 * dao_set_cell_expr absorbs the reference for the expr.
420 void
421 dao_set_cell_expr (data_analysis_output_t *dao, int col, int row,
422 GnmExpr const *expr)
424 GnmCell *cell;
425 GnmExprTop const *texpr;
426 GnmRange r;
428 range_init (&r, col, row, col, row);
430 if (!adjust_range (dao, &r)) {
431 gnm_expr_free (expr);
432 return;
435 cell = sheet_cell_fetch (dao->sheet, r.start.col, r.start.row);
436 texpr = gnm_expr_top_new (expr);
437 gnm_cell_set_expr (cell, texpr);
438 gnm_expr_top_unref (texpr);
443 * dao_set_cell_value:
444 * @dao:
445 * @col:
446 * @row:
447 * @v:
449 * set cell to a value
451 * Note: the rows/cols specification for all dao_set_cell_...
452 * commands are relative to the location of the output
457 void
458 dao_set_cell_value (data_analysis_output_t *dao, int col, int row, GnmValue *v)
460 GnmCell *cell;
461 GnmRange r;
463 range_init (&r, col, row, col, row);
465 if (!adjust_range (dao, &r)) {
466 value_release (v);
467 return;
470 cell = sheet_cell_fetch (dao->sheet, r.start.col, r.start.row);
472 sheet_cell_set_value (cell, v);
476 * dao_set_cell:
477 * @dao:
478 * @col:
479 * @row:
480 * @text:
482 * set cell to a string
486 void
487 dao_set_cell (data_analysis_output_t *dao, int col, int row, const char *text)
489 if (text == NULL) {
490 /* FIXME: should we erase instead? */
491 dao_set_cell_value (dao, col, row, value_new_empty ());
492 } else {
493 dao_set_cell_value (dao, col, row, value_new_string (text));
499 * dao_set_cell_printf:
500 * @dao:
501 * @col:
502 * @row:
503 * @fmt:
504 * @...:
506 * create format string and set cell.
509 void
510 dao_set_cell_printf (data_analysis_output_t *dao, int col, int row,
511 const char *fmt, ...)
513 char *buffer;
514 va_list args;
516 va_start (args, fmt);
517 buffer = g_strdup_vprintf (fmt, args);
518 va_end (args);
520 dao_set_cell_value (dao, col, row, value_new_string (buffer));
521 g_free (buffer);
526 * set_cell_float:
527 * @dao:
528 * @col:
529 * @row:
530 * @v:
532 * set cell to a gnm_float
536 void
537 dao_set_cell_float (data_analysis_output_t *dao, int col, int row, gnm_float v)
539 dao_set_cell_value (dao, col, row, value_new_float (v));
544 * set_cell_int:
545 * @dao:
546 * @col:
547 * @row:
548 * @v:
550 * set cell to an int
554 void
555 dao_set_cell_int (data_analysis_output_t *dao, int col, int row, int v)
557 dao_set_cell_value (dao, col, row, value_new_int (v));
562 * dao_set_cell_na:
563 * @dao:
564 * @col:
565 * @row:
567 * set cell to NA
571 void
572 dao_set_cell_na (data_analysis_output_t *dao, int col, int row)
574 dao_set_cell_value (dao, col, row, value_new_error_NA (NULL));
578 * dao_set_cell_float_na:
579 * @dao:
580 * @col:
581 * @row:
582 * @v:
583 * @is_valid:
585 * set cell to a gnm_float or NA as appropraite
589 void
590 dao_set_cell_float_na (data_analysis_output_t *dao, int col, int row,
591 gnm_float v, gboolean is_valid)
593 if (is_valid) {
594 dao_set_cell_float (dao, col, row, v);
595 } else {
596 dao_set_cell_na (dao, col, row);
601 * dao_set_cell_comment:
602 * @dao:
603 * @col:
604 * @row:
605 * @comment:
607 * set a cell comment
610 void
611 dao_set_cell_comment (data_analysis_output_t *dao, int col, int row,
612 const char *comment)
614 char const *author = NULL;
615 GnmRange r;
617 range_init (&r, col, row, col, row);
619 if (adjust_range (dao, &r))
620 cell_set_comment (dao->sheet, &r.start, author, comment, NULL);
625 * dao_autofit_these_columns:
626 * @dao:
627 * @from_col:
628 * @to_col:
630 * Fits the specified columns to their content
632 void
633 dao_autofit_these_columns (data_analysis_output_t *dao, int from_col, int to_col)
635 GnmRange r;
637 if (!dao->autofit_flag)
638 return;
640 range_init_cols (&r, dao->sheet,
641 from_col + dao->start_col,
642 to_col + dao->start_col);
644 colrow_autofit (dao->sheet, &r, TRUE,
645 FALSE, dao->autofit_noshrink, FALSE,
646 NULL, NULL);
650 * dao_autofit_columns:
651 * @dao:
653 * fits all columns to their content
655 void
656 dao_autofit_columns (data_analysis_output_t *dao)
658 dao_autofit_these_columns (dao, 0, dao->cols - 1);
661 void
662 dao_autofit_these_rows (data_analysis_output_t *dao, int from_row, int to_row)
664 GnmRange r;
666 if (!dao->autofit_flag)
667 return;
669 range_init_rows (&r, dao->sheet,
670 from_row + dao->start_row,
671 to_row + dao->start_row);
673 colrow_autofit (dao->sheet, &r, FALSE,
674 FALSE, dao->autofit_noshrink, FALSE,
675 NULL, NULL);
678 void
679 dao_autofit_rows (data_analysis_output_t *dao)
681 dao_autofit_these_rows (dao, 0, dao->rows - 1);
686 * dao_set_style:
687 * @dao:
688 * @col1:
689 * @row1:
690 * @col2:
691 * @row2:
692 * @style: (transfer full):
694 * Applies a partial style to the given region.
697 static void
698 dao_set_style (data_analysis_output_t *dao, int col1, int row1,
699 int col2, int row2, GnmStyle *mstyle)
701 GnmRange r;
703 range_init (&r, col1, row1, col2, row2);
705 if (!adjust_range (dao, &r)) {
706 gnm_style_unref (mstyle);
707 return;
710 sheet_style_apply_range (dao->sheet, &r, mstyle);
714 * dao_set_bold:
715 * @dao:
716 * @col1:
717 * @row1:
718 * @col2:
719 * @row2:
721 * sets the given cell range to bold
725 void
726 dao_set_bold (data_analysis_output_t *dao, int col1, int row1,
727 int col2, int row2)
729 GnmStyle *mstyle = gnm_style_new ();
731 gnm_style_set_font_bold (mstyle, TRUE);
733 dao_set_style (dao, col1, row1, col2, row2, mstyle);
737 * dao_set_italic:
738 * @dao:
739 * @col1:
740 * @row1:
741 * @col2:
742 * @row2:
744 * sets the given cell range to italic
748 void
749 dao_set_italic (data_analysis_output_t *dao, int col1, int row1,
750 int col2, int row2)
752 GnmStyle *mstyle = gnm_style_new ();
754 gnm_style_set_font_italic (mstyle, TRUE);
755 dao_set_style (dao, col1, row1, col2, row2, mstyle);
759 * dao_set_percent:
760 * @dao:
761 * @col1:
762 * @row1:
763 * @col2:
764 * @row2:
766 * set the given cell range to percent format
770 void
771 dao_set_percent (data_analysis_output_t *dao, int col1, int row1,
772 int col2, int row2)
774 GnmStyle *mstyle = gnm_style_new ();
775 gnm_style_set_format (mstyle, go_format_default_percentage ());
776 dao_set_style (dao, col1, row1, col2, row2, mstyle);
780 * dao_set_date:
781 * @dao:
782 * @col1:
783 * @row1:
784 * @col2:
785 * @row2:
787 * set the given cell range to date format
791 void
792 dao_set_date (data_analysis_output_t *dao, int col1, int row1,
793 int col2, int row2)
795 GnmStyle *mstyle = gnm_style_new ();
796 gnm_style_set_format (mstyle, go_format_default_date ());
797 dao_set_style (dao, col1, row1, col2, row2, mstyle);
801 * dao_set_format:
802 * @dao:
803 * @col1:
804 * @row1:
805 * @col2:
806 * @row2:
807 * @format:
809 * set the given cell range to given format
813 void
814 dao_set_format (data_analysis_output_t *dao, int col1, int row1,
815 int col2, int row2,
816 char const * format)
818 GOFormat *fmt;
820 fmt = go_format_new_from_XL (format);
821 if (go_format_is_invalid (fmt)) {
822 g_warning ("Ignoring invalid format [%s]", format);
823 } else {
824 GnmStyle *mstyle = gnm_style_new ();
825 gnm_style_set_format (mstyle, fmt);
826 dao_set_style (dao, col1, row1, col2, row2, mstyle);
828 go_format_unref (fmt);
833 * dao_set_colors:
834 * @dao:
835 * @col1:
836 * @row1:
837 * @col2:
838 * @row2:
840 * set the given cell range to given background and text colors
844 void
845 dao_set_colors (data_analysis_output_t *dao, int col1, int row1,
846 int col2, int row2,
847 GnmColor *fore, GnmColor *back)
849 GnmStyle *mstyle;
851 mstyle = gnm_style_new ();
852 if (fore)
853 gnm_style_set_font_color (mstyle, fore);
854 if (back) {
855 gnm_style_set_back_color (mstyle, back);
856 gnm_style_set_pattern (mstyle, 1);
858 dao_set_style (dao, col1, row1, col2, row2, mstyle);
862 * dao_set_align:
863 * @dao:
864 * @col1:
865 * @row1:
866 * @col2:
867 * @row2:
869 * set the given horizontal and vertical alignment to a cell range
873 void
874 dao_set_align (data_analysis_output_t *dao, int col1, int row1,
875 int col2, int row2,
876 GnmHAlign align_h, GnmVAlign align_v)
878 GnmStyle *mstyle;
880 mstyle = gnm_style_new ();
881 gnm_style_set_align_h (mstyle, align_h);
882 gnm_style_set_align_v (mstyle, align_v);
883 dao_set_style (dao, col1, row1, col2, row2, mstyle);
887 * dao_set_border:
888 * @dao:
889 * @col1:
890 * @row1:
891 * @col2:
892 * @row2:
897 void
898 dao_set_border (data_analysis_output_t *dao, int col1, int row1,
899 int col2, int row2,
900 GnmStyleElement elem, GnmStyleBorderType border,
901 GnmColor *color,
902 GnmStyleBorderOrientation orientation)
904 GnmStyle *mstyle;
906 mstyle = gnm_style_new ();
907 gnm_style_set_border (mstyle, elem,
908 gnm_style_border_fetch (border,
909 color,
910 orientation));
911 dao_set_style (dao, col1, row1, col2, row2, mstyle);
917 * dao_get_colrow_state_list:
918 * @dao:
919 * @is_cols:
922 * Returns: (transfer full):
924 ColRowStateList *
925 dao_get_colrow_state_list (data_analysis_output_t *dao, gboolean is_cols)
927 switch (dao->type) {
928 case NewSheetOutput:
929 case NewWorkbookOutput:
930 return NULL;
931 case RangeOutput:
932 if (is_cols)
933 return colrow_get_states
934 (dao->sheet, is_cols, dao->start_col,
935 dao->start_col + dao->cols - 1);
936 else
937 return colrow_get_states
938 (dao->sheet, is_cols, dao->start_row,
939 dao->start_row + dao->rows - 1);
940 default:
941 return NULL;
946 * dao_set_colrow_state_list:
947 * @dao:
948 * @is_cols:
949 * @list:
954 void
955 dao_set_colrow_state_list (data_analysis_output_t *dao, gboolean is_cols,
956 ColRowStateList *list)
958 g_return_if_fail (list);
960 if (dao->type == RangeOutput)
961 colrow_set_states (dao->sheet, is_cols,
962 is_cols ? dao->start_col : dao->start_row,
963 list);
966 void
967 dao_append_date (GString *buf)
969 GDate date;
970 struct tm tm_s;
971 gchar *tmp;
972 time_t now;
974 now = time (NULL);
975 g_date_set_time_t (&date, now);
976 g_date_to_struct_tm (&date, &tm_s);
977 tm_s.tm_sec = now % 60;
978 tm_s.tm_min = (now / 60) % 60;
979 tm_s.tm_hour = (now / 3600) % 24;
980 tmp = asctime (&tm_s);
981 g_string_append (buf, tmp);
985 * dao_write_header:
986 * @dao:
987 * @toolname: name of the tool, like Solver or Risk simulation
988 * @title:
989 * @sheet:
991 * Writes the titles of a report.
994 void
995 dao_write_header (data_analysis_output_t *dao, const gchar *toolname,
996 const gchar *title, Sheet *sheet)
998 GString *buf;
999 const char *uri;
1001 buf = g_string_new (NULL);
1002 g_string_append_printf (buf, "%s %s %s %s",
1003 _("Gnumeric "), toolname, VERSION, title);
1004 dao_set_cell (dao, 0, 0, buf->str);
1005 g_string_free (buf, FALSE);
1007 buf = g_string_new (NULL);
1008 uri = go_doc_get_uri (GO_DOC (sheet->workbook));
1009 g_string_append_printf (buf, "%s [%s]%s", _("Worksheet:"),
1010 uri,
1011 sheet->name_quoted);
1012 dao_set_cell (dao, 0, 1, buf->str);
1013 g_string_free (buf, FALSE);
1015 buf = g_string_new (NULL);
1016 g_string_append (buf, _("Report Created: "));
1017 dao_append_date (buf);
1018 dao_set_cell (dao, 0, 2, buf->str);
1019 g_string_free (buf, FALSE);
1021 dao_set_bold (dao, 0, 0, 0, 2);
1025 char *
1026 dao_find_name (Sheet *sheet, int col, int row)
1028 static char *str = NULL;
1029 const char *col_str = "";
1030 const char *row_str = "";
1031 int col_n, row_n;
1033 for (col_n = col - 1; col_n >= 0; col_n--) {
1034 GnmCell *cell = sheet_cell_get (sheet, col_n, row);
1035 if (cell && !VALUE_IS_NUMBER (cell->value)) {
1036 col_str = value_peek_string (cell->value);
1037 break;
1041 for (row_n = row - 1; row_n >= 0; row_n--) {
1042 GnmCell *cell = sheet_cell_get (sheet, col, row_n);
1043 if (cell && !VALUE_IS_NUMBER (cell->value)) {
1044 row_str = value_peek_string (cell->value);
1045 break;
1049 if (*col_str || *row_str) {
1050 str = g_new (char, strlen (col_str) + strlen (row_str) + 2);
1052 if (*col_str)
1053 sprintf (str, "%s %s", col_str, row_str);
1054 else
1055 sprintf (str, "%s", row_str);
1056 } else {
1057 const char *tmp = cell_coord_name (col, row);
1059 str = g_new (char, strlen (tmp) + 1);
1060 strcpy (str, tmp);
1063 return str;
1066 gboolean
1067 dao_put_formulas (data_analysis_output_t *dao)
1069 g_return_val_if_fail (dao != NULL, FALSE);
1070 return dao->put_formulas;
1073 static GnmValue *
1074 cb_convert_to_value (GnmCellIter const *iter, G_GNUC_UNUSED gpointer user)
1076 GnmCell *cell = iter->cell;
1077 if (!cell || !gnm_cell_has_expr (cell))
1078 return NULL;
1080 gnm_cell_eval (cell);
1082 if (gnm_expr_top_is_array_elem (cell->base.texpr, NULL, NULL))
1083 return NULL;
1085 gnm_cell_convert_expr_to_value (cell);
1086 return NULL;
1090 static void
1091 dao_convert_to_values (data_analysis_output_t *dao)
1093 if (dao->put_formulas)
1094 return;
1096 sheet_foreach_cell_in_region (dao->sheet, CELL_ITER_IGNORE_BLANK,
1097 dao->start_col, dao->start_row,
1098 dao->start_col + dao->cols - 1,
1099 dao->start_row + dao->rows - 1,
1100 cb_convert_to_value,
1101 NULL);
1104 void
1105 dao_redraw_respan (data_analysis_output_t *dao)
1107 GnmRange r;
1109 range_init (&r, dao->start_col, dao->start_row,
1110 dao->start_col + dao->cols - 1,
1111 dao->start_row + dao->rows - 1);
1112 sheet_range_calc_spans (dao->sheet, &r,
1113 GNM_SPANCALC_RESIZE | GNM_SPANCALC_RE_RENDER);
1114 sheet_region_queue_recalc (dao->sheet, &r);
1115 dao_convert_to_values (dao);
1116 sheet_redraw_range (dao->sheet, &r);
1120 static GnmExpr const *
1121 dao_get_cellref_full (data_analysis_output_t *dao, int x, int y, Sheet *sheet)
1123 GnmCellRef r;
1124 r.sheet = sheet;
1125 r.col = x + dao->start_col + dao->offset_col;
1126 r.col_relative = FALSE;
1127 r.row = y + dao->start_row + dao->offset_row;
1128 r.row_relative = FALSE;
1129 return gnm_expr_new_cellref (&r);
1132 GnmExpr const *
1133 dao_get_cellref (data_analysis_output_t *dao, int x, int y)
1135 return dao_get_cellref_full (dao, x, y, NULL);
1138 static GnmExpr const *
1139 dao_get_rangeref_full (data_analysis_output_t *dao, int ax, int ay, int bx, int by, Sheet *sheet)
1141 GnmValue *v;
1142 GnmCellRef ar;
1143 GnmCellRef br;
1145 ar.sheet = sheet;
1146 ar.col = ax + dao->start_col + dao->offset_col;
1147 ar.col_relative = FALSE;
1148 ar.row = ay + dao->start_row + dao->offset_row;
1149 ar.row_relative = FALSE;
1151 br.sheet = sheet;
1152 br.col = bx + dao->start_col + dao->offset_col;
1153 br.col_relative = FALSE;
1154 br.row = by + dao->start_row + dao->offset_row;
1155 br.row_relative = FALSE;
1157 v = value_new_cellrange (&ar, &br, 0, 0);
1158 return gnm_expr_new_constant (v);
1161 GnmExpr const *
1162 dao_get_rangeref (data_analysis_output_t *dao, int ax, int ay, int bx, int by)
1164 return dao_get_rangeref_full (dao, ax, ay, bx, by, NULL);
1167 void
1168 dao_set_sheet_object (data_analysis_output_t *dao, int col, int row, SheetObject* so)
1170 SheetObjectAnchor anchor;
1171 GnmRange anchor_r;
1173 g_return_if_fail (so != NULL);
1175 if (dao->omit_so) {
1176 g_object_unref (so);
1177 return;
1180 range_init (&anchor_r, dao->start_col + col, dao->start_row + row,
1181 dao->start_col + ((dao->cols < 5) ? dao->cols : 5),
1182 dao->start_row + ((dao->rows < 20) ? dao->rows : 20));
1184 sheet_object_anchor_init (&anchor, &anchor_r, NULL, GOD_ANCHOR_DIR_UNKNOWN,
1185 GNM_SO_ANCHOR_TWO_CELLS);
1186 sheet_object_set_anchor (so, &anchor);
1187 sheet_object_set_sheet (so, dao->sheet);
1189 dao->sos = g_slist_prepend (dao->sos, so);
1193 * dao_go_data_vector:
1194 * @dao:
1195 * @ax:
1196 * @ay:
1197 * @bx:
1198 * @by:
1200 * Returns: (transfer full):
1202 GOData *
1203 dao_go_data_vector (data_analysis_output_t *dao, int ax, int ay, int bx, int by)
1205 return gnm_go_data_vector_new_expr (dao->sheet, gnm_expr_top_new (dao_get_rangeref_full (dao, ax, ay, bx, by, dao->sheet)));
1209 * dao_surrender_so:
1210 * @dao:
1212 * Returns: (element-type GObject) (transfer full):
1214 GSList *
1215 dao_surrender_so (data_analysis_output_t *dao)
1217 GSList *l = dao->sos;
1218 dao->sos = NULL;
1220 return l;
1223 void
1224 dao_set_omit_so (data_analysis_output_t *dao, gboolean omit)
1226 dao->omit_so = omit;
1231 void
1232 dao_set_merge (data_analysis_output_t *dao, int col1, int row1,
1233 int col2, int row2)
1235 GnmRange r;
1237 range_init (&r, col1, row1, col2, row2);
1238 if (adjust_range (dao, &r))
1239 gnm_sheet_merge_add (dao->sheet, &r, TRUE, NULL);