gnumeric r16778 - in trunk: . src src/dialogs src/tools



Author: guelzow
Date: Mon Sep  8 00:28:03 2008
New Revision: 16778
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16778&view=rev

Log:
2008-09-07  Andreas J. Guelzow <aguelzow pyrshep ca>

	* regression.glade: remove "group by" buttons and add
	  warnings label
	* dialog-analysis-tools.c (regression_tool_calc_*): new
	(regression_tool_ok_clicked_cb): keep arrays and 
	  determine group-by from y variable
	(regression_tool_update_sensitivity_cb): provide reasons
	  and also check for correct range sizes
	(dialog_regression): enable choice to enter formulas rather than 
	  values

2008-09-07  Andreas Guelzow  <aguelzow pyrshep ca>

	* src/expr.h (gnm_expr_new_funcall4): new
	* src/expr.c (gnm_expr_new_funcall4): new

2008-09-07  Andreas J. Guelzow <aguelzow pyrshep ca>

	* dao.h (dao_set_format): new
	(dao_set_array_expr): new
	(dao_get_cellref): new
	* dao.c (dao_set_format): new
	(dao_set_array_expr): new
	(dao_set_cell_array_expr): use dao_set_array_expr
	(dao_get_cellref): new
	* analysis-tools.h (analysis_tools_error_code_t): remove
	  analysis_tools_REG_invalid_dimensions
	(analysis_tools_data_regression_t): switch to ftest base
	* analysis-tools.c (analysis_tools_write_label_ftest): use
	  cb_adjust_areas
	(cb_cut_into_rows): ditto
	(cb_cut_into_cols): ditto
	(analysis_tool_regression_engine_last_check): deleted
	(calculate_xdim): new
	(analysis_tool_regression_engine_run): rewritten
	(analysis_tool_regression_engine): simplify




Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/src/dialogs/ChangeLog
   trunk/src/dialogs/dialog-analysis-tools.c
   trunk/src/dialogs/regression.glade
   trunk/src/expr.c
   trunk/src/expr.h
   trunk/src/tools/ChangeLog
   trunk/src/tools/analysis-tools.c
   trunk/src/tools/analysis-tools.h
   trunk/src/tools/dao.c
   trunk/src/tools/dao.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Mon Sep  8 00:28:03 2008
@@ -6,6 +6,7 @@
 	* Fix column ordering in analysis tools. [#516052]
 	* Make the paired t-test analysis tool use only 
 	  complete pairs. [# 531852]
+	* Improve regression tool
 
 Jean:
 	* Fix printing of rotated text. [#539734]

Modified: trunk/src/dialogs/dialog-analysis-tools.c
==============================================================================
--- trunk/src/dialogs/dialog-analysis-tools.c	(original)
+++ trunk/src/dialogs/dialog-analysis-tools.c	Mon Sep  8 00:28:03 2008
@@ -335,7 +335,7 @@
 		table = GTK_TABLE (glade_xml_get_widget (state->gui,
 							 "input-table"));
 		state->input_entry = gnm_expr_entry_new (state->wbcg, TRUE);
-		gnm_expr_entry_set_flags (state->input_entry, flags,
+		gnm_expr_entry_set_flags (state->input_entry, flags | GNM_EE_FORCE_ABS_REF,
 					  GNM_EE_MASK);
 		gtk_table_attach (table, GTK_WIDGET (state->input_entry),
 				  1, 2, 0, 1,
@@ -365,7 +365,7 @@
 
 		state->input_entry_2 = gnm_expr_entry_new (state->wbcg, TRUE);
 		gnm_expr_entry_set_flags (state->input_entry_2,
-					  GNM_EE_SINGLE_RANGE, GNM_EE_MASK);
+					  GNM_EE_SINGLE_RANGE | GNM_EE_FORCE_ABS_REF, GNM_EE_MASK);
 		table = GTK_TABLE (gtk_widget_get_parent (widget));
 
 		this_label_widget = g_list_find_custom
@@ -1909,6 +1909,26 @@
 /*  Begin of Regression tool code */
 /**********************************************/
 
+static gint
+regression_tool_calc_height (GnmValue *val)
+{
+		GnmRange r;
+
+		if (NULL == range_init_value (&r, val))
+			return 0;
+		return range_height (&r);
+}
+
+static gint
+regression_tool_calc_width (GnmValue *val)
+{
+		GnmRange r;
+
+		if (NULL == range_init_value (&r, val))
+			return 0;
+		return range_width (&r);
+}
+
 
 /**
  * regression_tool_ok_clicked_cb:
@@ -1929,6 +1949,7 @@
 	GtkWidget *w;
 	gint err;
 	gnm_float confidence;
+	gint y_h, y_w;
 
 	if (state->base.warning_dialog != NULL)
 		gtk_widget_destroy (state->base.warning_dialog);
@@ -1938,17 +1959,21 @@
 
 	data->base.wbc = WORKBOOK_CONTROL (state->base.wbcg);
 
-	data->base.input = gnm_expr_entry_parse_as_list (
+	data->base.range_1 = gnm_expr_entry_parse_as_value (
 		GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
-	data->y_input = gnm_expr_entry_parse_as_value
+	data->base.range_2 = gnm_expr_entry_parse_as_value
 		(GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
-	data->base.group_by = gnumeric_glade_group_value (state->base.gui, grouped_by_group);
+
+	y_h = regression_tool_calc_height(data->base.range_2);
+	y_w = regression_tool_calc_width (data->base.range_2);
+
+	data->group_by = (y_h == 1) ? GROUPED_BY_ROW : GROUPED_BY_COL;
 
 	w = glade_xml_get_widget (state->base.gui, "labels_button");
         data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
 
 	err = entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, TRUE);
-	data->alpha = 1 - confidence;
+	data->base.alpha = 1 - confidence;
 
 	w = glade_xml_get_widget (state->base.gui, "intercept-button");
 	data->intercept = 1 - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
@@ -1957,35 +1982,18 @@
 			       dao, data, analysis_tool_regression_engine)) {
 		char *text;
 
-		switch ( data->base.err) {
-		case analysis_tools_reported_err_input:
-			gnm_expr_entry_grab_focus
-				(GNM_EXPR_ENTRY (state->base.input_entry),
-				 TRUE);
-			break;
-		case analysis_tools_reported_err:
-			break;
-		case  analysis_tools_REG_invalid_dimensions:
-			error_in_entry ((GenericToolState *) state,
-					GTK_WIDGET (state->base.input_entry),
-			      _("There must be an equal number of entries "
-				"for each variable in the regression."));
-			break;
-		default:
-			text = g_strdup_printf (
-				_("An unexpected error has occurred: %d."), data->base.err);
-			error_in_entry ((GenericToolState *) state,
-					GTK_WIDGET (state->base.input_entry), text);
-			g_free (text);
-			break;
-		}
-		if (data->base.input)
-			range_list_destroy (data->base.input);
-		if (data->y_input)
-			value_release (data->y_input);
+		text = g_strdup_printf (
+			_("An unexpected error has occurred: %d."), data->base.err);
+		error_in_entry ((GenericToolState *) state,
+				GTK_WIDGET (state->base.input_entry), text);
+		g_free (text);
+		
+		if (data->base.range_1)
+			value_release (data->base.range_1);
+		if (data->base.range_2)
+			value_release (data->base.range_2);
 		g_free (dao);
 		g_free (data);
-
 	} else
 		gtk_widget_destroy (state->base.dialog);
 
@@ -2004,35 +2012,91 @@
 regression_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
 				       RegressionToolState *state)
 {
-	gboolean ready  = FALSE;
-	gboolean input_1_ready  = FALSE;
-	gboolean input_2_ready  = FALSE;
-	gboolean output_ready  = FALSE;
 	int err;
 	gnm_float confidence;
-        GSList *input_range;
+        GnmValue *input_range;
         GnmValue *input_range_2;
+	gint y_h, y_w;
+	gint x_h, x_w;
 
-        input_range = gnm_expr_entry_parse_as_list (
-		GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
-	input_range_2 = gnm_expr_entry_parse_as_value
-		(GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
+	/* Checking Input Range */
+        input_range_2 = gnm_expr_entry_parse_as_value (
+		GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
+	if (input_range_2 == NULL) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The y variable range is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+	
+	y_h = regression_tool_calc_height(input_range_2);
+	y_w = regression_tool_calc_width (input_range_2);
+	value_release (input_range_2);
 
-	err = entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, FALSE);
+	if (y_h == 0 || y_w == 0) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The y variable range is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+	if (y_h != 1 && y_w != 1) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The y variable range must be a vector (n by 1 or 1 by n)."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+	if (y_h <= 2 && y_w <= 2) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The y variable range is to small"));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
 
-	input_1_ready = (input_range != NULL);
-	input_2_ready = (input_range_2 != NULL);
-	output_ready =  gnm_dao_is_ready (GNM_DAO (state->base.gdao));
+	input_range = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
+	if (input_range == NULL) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The x variables range is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
 
-	ready = input_1_ready &&
-		input_2_ready &&
-		(err == 0) && (1 > confidence ) && (confidence > 0) &&
-		output_ready;
+	x_h = regression_tool_calc_height(input_range);
+	x_w = regression_tool_calc_width (input_range);
+	value_release (input_range);
 
-        if (input_range != NULL) range_list_destroy (input_range);
-        if (input_range_2 != NULL) value_release (input_range_2);
+	if (x_h == 0 || x_w == 0) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The x variables range is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+	
+	if ((y_h == 1 && y_w != x_w) || (y_w == 1 && y_h != x_h)) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The sizes of the x variable and y variable ranges do not match."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
 
-	gtk_widget_set_sensitive (state->base.ok_button, ready);
+	err = entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, FALSE);
+
+	if (err != 0 || (1 < confidence || confidence < 0)) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The confidence level is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+
+        if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The output specification "
+				      "is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);		
+	}
+
+	gtk_label_set_text (GTK_LABEL (state->base.warning), "");
+	gtk_widget_set_sensitive (state->base.ok_button, TRUE);
 }
 
 /**
@@ -2066,7 +2130,7 @@
 			      REGRESSION_KEY,
 			      G_CALLBACK (regression_tool_ok_clicked_cb), NULL,
 			      G_CALLBACK (regression_tool_update_sensitivity_cb),
-			      0))
+			      GNM_EE_SINGLE_RANGE))
 		return 0;
 
 	state->confidence_entry = glade_xml_get_widget (state->base.gui, "confidence-entry");
@@ -2077,7 +2141,7 @@
 	gnumeric_editable_enters (GTK_WINDOW (state->base.dialog),
 				  GTK_WIDGET (state->confidence_entry));
 
-	gnm_dao_set_put (GNM_DAO (state->base.gdao), FALSE, FALSE);
+	gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
 	regression_tool_update_sensitivity_cb (NULL, state);
 	tool_load_selection ((GenericToolState *)state, TRUE);
 

Modified: trunk/src/dialogs/regression.glade
==============================================================================
--- trunk/src/dialogs/regression.glade	(original)
+++ trunk/src/dialogs/regression.glade	Mon Sep  8 00:28:03 2008
@@ -1,433 +1,252 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
 <glade-interface>
-
-<widget class="GtkDialog" id="Regression">
-  <property name="title" translatable="yes">Regression</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="has_separator">False</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">8</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="hbuttonbox1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="helpbutton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-help</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="response_id">0</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="response_id">0</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="has_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="response_id">0</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkNotebook" id="notebook1">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="show_tabs">True</property>
-	  <property name="show_border">True</property>
-	  <property name="tab_pos">GTK_POS_TOP</property>
-	  <property name="scrollable">False</property>
-	  <property name="enable_popup">False</property>
-
-	  <child>
-	    <widget class="GtkTable" id="input-table">
-	      <property name="border_width">12</property>
-	      <property name="visible">True</property>
-	      <property name="n_rows">4</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">6</property>
-	      <property name="column_spacing">12</property>
-
-	      <child>
-		<widget class="GtkLabel" id="var1-label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_X variables:</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="var2-label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Y variable:</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">2</property>
-		  <property name="bottom_attach">3</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkCheckButton" id="labels_button">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">_Labels</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">3</property>
-		  <property name="bottom_attach">4</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label8">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Grouped by:</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_CENTER</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkHBox" id="hbox2">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkRadioButton" id="grouped_by_col">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Columns</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="active">True</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkRadioButton" id="grouped_by_row">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Rows</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		      <property name="group">grouped_by_col</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkRadioButton" id="grouped_by_area">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Areas</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		      <property name="group">grouped_by_col</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="y_options">fill</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label10">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">_Input</property>
-	      <property name="use_underline">True</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox2">
-	      <property name="border_width">12</property>
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkHBox" id="hbox1">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label7">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Confidence level:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_CENTER</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">5</property>
-		      <property name="ypad">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="confidence-entry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes">0.95</property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char" translatable="yes">*</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkCheckButton" id="intercept-button">
-		  <property name="border_width">3</property>
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">_Force intercept to be zero</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label11">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">O_ptions</property>
-	      <property name="use_underline">True</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="dao">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label12">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">_Output</property>
-	      <property name="use_underline">True</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
+  <widget class="GtkDialog" id="Regression">
+    <property name="title" translatable="yes">Regression</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">8</property>
+        <child>
+          <widget class="GtkNotebook" id="notebook1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <widget class="GtkTable" id="input-table">
+                <property name="visible">True</property>
+                <property name="border_width">12</property>
+                <property name="n_rows">3</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">12</property>
+                <property name="row_spacing">6</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="var1-label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">5</property>
+                    <property name="label" translatable="yes">_X variables:</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="var2-label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">5</property>
+                    <property name="label" translatable="yes">_Y variable:</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="labels_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">_Labels</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label10">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">_Input</property>
+                <property name="use_underline">True</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <property name="border_width">12</property>
+                <child>
+                  <widget class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkLabel" id="label7">
+                        <property name="visible">True</property>
+                        <property name="xpad">5</property>
+                        <property name="label" translatable="yes">Confidence level:</property>
+                        <property name="justify">GTK_JUSTIFY_CENTER</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="confidence-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">*</property>
+                        <property name="text" translatable="yes">0.95</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="intercept-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="border_width">3</property>
+                    <property name="label" translatable="yes">_Force intercept to be zero</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label11">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">O_ptions</property>
+                <property name="use_underline">True</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="dao">
+                <property name="visible">True</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label12">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">_Output</property>
+                <property name="use_underline">True</property>
+              </widget>
+              <packing>
+                <property name="type">tab</property>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkLabel" id="warnings">
+            <property name="visible">True</property>
+            <property name="justify">GTK_JUSTIFY_CENTER</property>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="hbuttonbox1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="helpbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-help</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="cancelbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="okbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="label">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>

Modified: trunk/src/expr.c
==============================================================================
--- trunk/src/expr.c	(original)
+++ trunk/src/expr.c	Mon Sep  8 00:28:03 2008
@@ -153,6 +153,21 @@
 	return gnm_expr_new_funcallv (func, 3, argv);
 }
 
+GnmExpr const *
+gnm_expr_new_funcall4 (GnmFunc *func,
+		       GnmExpr const *arg0,
+		       GnmExpr const *arg1,
+		       GnmExpr const *arg2,
+		       GnmExpr const *arg3)
+{
+	GnmExprConstPtr *argv = g_new (GnmExprConstPtr, 4);
+	argv[0] = arg0;
+	argv[1] = arg1;
+	argv[2] = arg2;
+	argv[3] = arg3;
+	return gnm_expr_new_funcallv (func, 4, argv);
+}
+
 
 /***************************************************************************/
 

Modified: trunk/src/expr.h
==============================================================================
--- trunk/src/expr.h	(original)
+++ trunk/src/expr.h	Mon Sep  8 00:28:03 2008
@@ -63,6 +63,11 @@
 					 GnmExpr const *arg0,
 					 GnmExpr const *arg1,
 					 GnmExpr const *arg2);
+GnmExpr const *gnm_expr_new_funcall4	(GnmFunc *func,
+					 GnmExpr const *arg0,
+					 GnmExpr const *arg1,
+					 GnmExpr const *arg2,
+					 GnmExpr const *arg3);
 GnmExpr const *gnm_expr_new_name	(GnmNamedExpr *name,
 					 Sheet *sheet_scope, Workbook *wb_scope);
 GnmExpr const *gnm_expr_new_cellref	(GnmCellRef const *cr);

Modified: trunk/src/tools/analysis-tools.c
==============================================================================
--- trunk/src/tools/analysis-tools.c	(original)
+++ trunk/src/tools/analysis-tools.c	Mon Sep  8 00:28:03 2008
@@ -79,6 +79,27 @@
 	Sheet *sheet;
 } data_list_specs_t;
 
+/*
+ *  cb_adjust_areas:
+ *  @data:
+ *  @user_data:
+ *
+ */
+static void
+cb_adjust_areas (gpointer data, G_GNUC_UNUSED gpointer user_data)
+{
+	GnmValue *range = (GnmValue *)data;
+
+	if (range == NULL || (range->type != VALUE_CELLRANGE)) {
+		return;
+	}
+
+	range->v_range.cell.a.col_relative = 0;
+	range->v_range.cell.a.row_relative = 0;
+	range->v_range.cell.b.col_relative = 0;
+	range->v_range.cell.b.row_relative = 0;
+}
+
 static GnmValue *
 cb_store_data (GnmCellIter const *iter, gpointer user)
 {
@@ -327,10 +348,7 @@
 analysis_tools_write_label_ftest (GnmValue *val, data_analysis_output_t *dao,
 				  int x, int y, gboolean labels, int i)
 {
-	val->v_range.cell.a.col_relative = 0;
-	val->v_range.cell.a.row_relative = 0;
-	val->v_range.cell.b.col_relative = 0;
-	val->v_range.cell.b.row_relative = 0;
+	cb_adjust_areas (val, NULL);
 
 	if (labels) {
 		GnmValue *label = value_dup (val);
@@ -372,10 +390,7 @@
 		return;
 	}
 
-	range->v_range.cell.a.col_relative = 0;
-	range->v_range.cell.a.row_relative = 0;
-	range->v_range.cell.b.col_relative = 0;
-	range->v_range.cell.b.row_relative = 0;
+	cb_adjust_areas (data, NULL);
 
 	if (range->v_range.cell.a.col == range->v_range.cell.b.col) {
 		*list_of_units = g_slist_prepend (*list_of_units, range);
@@ -416,10 +431,7 @@
 		return;
 	}
 
-	range->v_range.cell.a.col_relative = 0;
-	range->v_range.cell.a.row_relative = 0;
-	range->v_range.cell.b.col_relative = 0;
-	range->v_range.cell.b.row_relative = 0;
+	cb_adjust_areas (data, NULL);
 
 	if (range->v_range.cell.a.row == range->v_range.cell.b.row) {
 		*list_of_units = g_slist_prepend (*list_of_units, range);
@@ -436,26 +448,6 @@
 	return;
 }
 
-/*
- *  cb_adjust_areas:
- *  @data:
- *  @user_data:
- *
- */
-static void
-cb_adjust_areas (gpointer data, G_GNUC_UNUSED gpointer user_data)
-{
-	GnmValue *range = (GnmValue *)data;
-
-	if (range == NULL || (range->type != VALUE_CELLRANGE)) {
-		return;
-	}
-
-	range->v_range.cell.a.col_relative = 0;
-	range->v_range.cell.a.row_relative = 0;
-	range->v_range.cell.b.col_relative = 0;
-	range->v_range.cell.b.row_relative = 0;
-}
 
 /*
  *  prepare_input_range:
@@ -2551,6 +2543,9 @@
 
 	GnmFunc *fd_finv;
 
+	g_warning ("val_1 %s", value_peek_string (val_1));
+	g_warning ("val_2 %s", value_peek_string (val_2));
+
 	fd_finv = gnm_func_lookup ("FINV", NULL);
 	gnm_func_ref (fd_finv);
 
@@ -2847,14 +2842,20 @@
  *
  **/
 
-static gboolean
-analysis_tool_regression_engine_last_check (G_GNUC_UNUSED data_analysis_output_t *dao,
-					    G_GNUC_UNUSED analysis_tools_data_regression_t *info)
+static gint
+calculate_xdim (GnmValue *input, group_by_t  group_by)
 {
-	/* FIXME: code from ...engine_run that may lead to error               */
-	/* messages and no dao output should be moved here.                    */
-	/* data can be transported from here to ..._run via the result pointer */
-	return FALSE;
+		GnmRange r;
+
+		g_return_val_if_fail (input != NULL, 0);
+
+		if (NULL == range_init_value (&r, input))
+			return 0;
+
+		if (group_by == GROUPED_BY_ROW)
+			return range_height (&r);
+		
+		return range_width (&r);
 }
 
 
@@ -2862,127 +2863,65 @@
 analysis_tool_regression_engine_run (data_analysis_output_t *dao,
 				     analysis_tools_data_regression_t *info)
 {
-	GSList       *missing       = NULL;
-	GPtrArray    *x_data        = NULL;
-	data_set_t   *y_data        = NULL;
-	char         *text          = NULL;
-	char         *format;
-	gnm_regression_stat_t   *regression_stat = NULL;
-	gnm_float   r;
-	gnm_float   *res,  **xss;
-	int          i;
-	int          xdim;
-	RegressionResult regerr;
-	int          cor_err        = 0;
-
-
-	/* read the data */
-	x_data = new_data_set_list (info->base.input, info->base.group_by,
-				  FALSE, info->base.labels, dao->sheet);
-	xdim = x_data->len;
-	y_data = new_data_set (info->y_input, FALSE, info->base.labels,
-			       _("Y Variable"), 0, dao->sheet);
-
-	if (y_data->data->len != ((data_set_t *)g_ptr_array_index (x_data, 0))->data->len) {
-		destroy_data_set (y_data);
-		destroy_data_set_list (x_data);
-		gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-			_("There must be an equal number of entries for each variable in the regression."));
-		info->base.err = analysis_tools_reported_err_input;
-		return TRUE;
-	}
+	gint xdim = calculate_xdim (info->base.range_1, info->group_by);
+	gint i;
 
-	/* create a list of all missing or incomplete observations */
-	missing = g_slist_copy (y_data->missing);
-	for (i = 0; i < xdim; i++) {
-		data_set_t *this_data = g_ptr_array_index (x_data, i);
-		GSList *this_missing = this_data->missing;
-		missing = gnm_slist_sort_merge (missing, g_slist_copy (this_missing));
-	}
-
-	if (missing != NULL) {
-		gnm_strip_missing (y_data->data, missing);
-		for (i = 0; i < xdim; i++) {
-			data_set_t *this_data = g_ptr_array_index (x_data, i);
-			gnm_strip_missing (this_data->data, missing);
-		}
-		g_slist_free (missing);
-	}
-
-	/* data is now clean and ready */
-	xss = g_new (gnm_float *, xdim);
-	res = g_new (gnm_float, xdim + 1);
-
-	for (i = 0; i < xdim; i++) {
-		data_set_t *this_data = g_ptr_array_index (x_data, i);
-		xss[i] = (gnm_float *)(this_data->data->data);
-	}
-
-	regression_stat = gnm_regression_stat_new ();
-	regerr = gnm_linear_regression (xss, xdim,
-				    (gnm_float *)(y_data->data->data),
-				    y_data->data->len,
-				    info->intercept, res, regression_stat);
-
-	if (regerr != REG_ok && regerr != REG_near_singular_good) {
-		gnm_regression_stat_destroy (regression_stat);
-		destroy_data_set (y_data);
-		destroy_data_set_list (x_data);
-		g_free (xss);
-		g_free (res);
-		switch (regerr) {
-		case REG_not_enough_data:
-			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-					 _("There are too few data points to conduct this "
-					   "regression.\nThere must be at least as many "
-					   "data points as free variables."));
-			info->base.err = analysis_tools_reported_err_input;
-			break;
-
-		case REG_near_singular_bad:
-			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-					 _("Two or more of the independent variables "
-					   "are nearly linearly\ndependent.  All numerical "
-					   "precision was lost in the computation."));
-			info->base.err = analysis_tools_reported_err_input;
-			break;
-
-		case REG_singular:
-			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-					 _("Two or more of the independent variables "
-					   "are linearly\ndependent, and the regression "
-					   "cannot be calculated.\n\nRemove one of these\n"
-					   "variables and try the regression again."));
-			info->base.err = analysis_tools_reported_err_input;
-			break;
-
-		case REG_invalid_data:
-		case REG_invalid_dimensions:
-			gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-					 _("There must be an equal number of entries "
-					   "for each variable in the regression."));
-			info->base.err = analysis_tools_reported_err_input;
-			break;
-		default:
-			break;
-		}
-
-		return TRUE;
-	}
+	GnmValue *val_1 = value_dup (info->base.range_1);
+	GnmValue *val_2 = value_dup (info->base.range_2);
+	GnmValue *val_1_cp = NULL;
+	GnmValue *val_2_cp = NULL;
+
+	GnmExpr const *expr_x;
+	GnmExpr const *expr_y;
+	GnmExpr const *expr_linest;
+	GnmExpr const *expr_intercept;
+	GnmExpr const *expr_ms;
+	GnmExpr const *expr_sum;
+	GnmExpr const *expr_tstat;
+	GnmExpr const *expr_pvalue;
+	GnmExpr const *expr_n;
+	GnmExpr const *expr_df;
+	GnmExpr const *expr_lower;
+	GnmExpr const *expr_upper;
+	GnmExpr const *expr_confidence;
+
+	GnmFunc *fd_linest;
+	GnmFunc *fd_index;
+	GnmFunc *fd_fdist;
+	GnmFunc *fd_sum;
+	GnmFunc *fd_sqrt;
+	GnmFunc *fd_tdist;
+	GnmFunc *fd_tinv;
+	GnmFunc *fd_transpose;
 
+	fd_linest = gnm_func_lookup ("LINEST", NULL);
+	gnm_func_ref (fd_linest);
+	fd_index = gnm_func_lookup ("INDEX", NULL);
+	gnm_func_ref (fd_index);
+	fd_fdist = gnm_func_lookup ("FDIST", NULL);
+	gnm_func_ref (fd_fdist);
+	fd_sum = gnm_func_lookup ("SUM", NULL);
+	gnm_func_ref (fd_sum);
+	fd_sqrt = gnm_func_lookup ("SQRT", NULL);
+	gnm_func_ref (fd_sqrt);
+	fd_tdist = gnm_func_lookup ("TDIST", NULL);
+	gnm_func_ref (fd_tdist);
+	fd_tinv = gnm_func_lookup ("TINV", NULL);
+	gnm_func_ref (fd_tinv);
+	fd_transpose = gnm_func_lookup ("TRANSPOSE", NULL);
+	gnm_func_ref (fd_transpose);
 
-/* FIXME: virtually all the code above needs to be moved from here into  */
-/*        analysis_tool_regression_engine_last_check                     */
-/*        we have to figure out which data we have to trnasfer from      */
-/*        to here */
+	cb_adjust_areas (val_1, NULL);
+	cb_adjust_areas (val_2, NULL);
 
+	dao_set_italic (dao, 0, 0, 0, 16 + xdim);
         set_cell_text_col (dao, 0, 0, _("/SUMMARY OUTPUT"
 					"/"
 					"/Regression Statistics"
 					"/Multiple R"
-					"/R Square"
-					"/Adjusted R Square"
+					"/R^2"
 					"/Standard Error"
+					"/Adjusted R^2"
 					"/Observations"
 					"/"
 					"/ANOVA"
@@ -2993,147 +2932,342 @@
 					"/"
 					"/"
 					"/Intercept"));
-	for (i = 0; i < xdim; i++) {
-		data_set_t *this_data = g_ptr_array_index (x_data, i);
-		dao_set_cell (dao, 0, 17 + i, this_data->label);
+
+	if (info->base.labels) {
+		val_1_cp =  value_dup (val_1);
+		val_2_cp =  value_dup (val_2);
+		if (info->group_by == GROUPED_BY_ROW) {
+			val_1->v_range.cell.a.col++;
+			val_2->v_range.cell.a.col++;
+			val_1_cp->v_range.cell.b.col = val_1_cp->v_range.cell.a.col;
+			dao_set_array_expr (dao, 0, 17, 1, xdim, gnm_expr_new_constant 
+					    (value_dup (val_1_cp)));
+		} else {
+			val_1->v_range.cell.a.row++;
+			val_2->v_range.cell.a.row++;
+			val_1_cp->v_range.cell.b.row = val_1_cp->v_range.cell.a.row;
+			dao_set_array_expr (dao, 0, 17, 1, xdim, gnm_expr_new_funcall1 
+					    (fd_transpose,
+					     gnm_expr_new_constant (value_dup (val_1_cp))));
+		}
 	}
-	dao_set_italic (dao, 0, 0, 0, 16 + xdim);
 
+	dao_set_italic (dao, 1, 10, 5, 10);
         set_cell_text_row (dao, 1, 10, _("/df"
 					 "/SS"
 					 "/MS"
 					 "/F"
 					 "/Significance of F"));
-	dao_set_italic (dao, 1, 10, 5, 10);
 
-	format = g_strdup_printf (_("/Coefficients"
-				    "/Standard Error"
-				    "/t Stat"
-				    "/P-value"
-				    "/Lower %%0.0%s%%%%"
-				    "/Upper %%0.0%s%%%%"),
-				  GNM_FORMAT_f,
-				  GNM_FORMAT_f);
-	text = g_strdup_printf (format,
-				(1.0 - info->alpha) * 100,
-				(1.0 - info->alpha) * 100);
-	g_free (format);
-        set_cell_text_row (dao, 1, 15, text);
-	dao_set_italic (dao, 1, 15, 6, 15);
-	g_free (text);
+ 	dao_set_italic (dao, 1, 15, 6, 15);
+	set_cell_text_row (dao, 1, 15, _("/Coefficients" 
+					 "/Standard Error"
+					 "/t-Statistics"
+					 "/p-Value"));
+
+	dao_set_format  (dao, 5, 15, 5, 15, _("\"Lower\" 0%"));
+	dao_set_format  (dao, 6, 15, 6, 15, _("\"Upper\" 0%"));
+	dao_set_align (dao, 5, 15, 5, 15, HALIGN_LEFT, VALIGN_TOP);
+	dao_set_align (dao, 6, 15, 6, 15, HALIGN_RIGHT, VALIGN_TOP);
+
+	dao_set_cell_float (dao, 5, 15, 1.0 - info->base.alpha);
+	dao_set_cell_expr (dao, 6, 15, make_cellref (-1, 0));
+	expr_confidence = dao_get_cellref (dao, 5, 15);
 
 	dao_set_cell_comment (dao, 4, 15,
 			      _("Probability of an observation's absolute value being larger than the t-value's"));
 
-	if (xdim == 1)
-		cor_err =  gnm_range_correl_pop (xss[0], (gnm_float *)(y_data->data->data),
-					     y_data->data->len, &r);
-	else r = gnm_sqrt (regression_stat->sqr_r);
+	expr_x = gnm_expr_new_constant (value_dup (val_1));
+	expr_y = gnm_expr_new_constant (value_dup (val_2));
+
+	expr_intercept = gnm_expr_new_constant (value_new_bool (info->intercept));
+	
+	expr_linest = gnm_expr_new_funcall4 (fd_linest,
+					     expr_y,
+					     expr_x,
+					     expr_intercept,
+					     gnm_expr_new_constant (value_new_bool (TRUE)));
+		
 
 	/* Multiple R */
-	dao_set_cell_float_na (dao, 1, 3, r, cor_err == 0);
+	if (info->intercept) {
+		if (dao_cell_is_visible (dao, 1, 4))
+			dao_set_cell_expr (dao, 1, 3, gnm_expr_new_funcall1 (fd_sqrt, make_cellref (0, 1)));
+		else
+			dao_set_cell_expr (dao, 1, 3, 
+					   gnm_expr_new_funcall1 (fd_sqrt, gnm_expr_new_funcall3 
+								  (fd_index, 
+								   gnm_expr_copy (expr_linest),
+								   gnm_expr_new_constant (value_new_int (3)),
+								   gnm_expr_new_constant (value_new_int (1)))));
+	} else
+			dao_set_cell_expr (dao, 1, 3, 
+					   gnm_expr_new_funcall1 (fd_sqrt, gnm_expr_new_funcall3 
+								  (fd_index, 
+								   gnm_expr_new_funcall4 
+								   (fd_linest,
+								    gnm_expr_new_constant (value_dup (val_2)),
+								    gnm_expr_new_constant (value_dup (val_1)),
+								    gnm_expr_new_constant (value_new_bool (TRUE)),
+								    gnm_expr_new_constant (value_new_bool (TRUE))),
+								   gnm_expr_new_constant (value_new_int (3)),
+								   gnm_expr_new_constant (value_new_int (1)))));
+		
 
 	/* R Square */
-	dao_set_cell_float (dao, 1, 4, regression_stat->sqr_r);
+	dao_set_cell_array_expr (dao, 1, 4, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (3)),
+							gnm_expr_new_constant (value_new_int (1))));
+	
+	/* Standard Error */
+	dao_set_cell_array_expr (dao, 1, 5, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (3)),
+							gnm_expr_new_constant (value_new_int (2))));
 
 	/* Adjusted R Square */
-	dao_set_cell_float (dao, 1, 5, regression_stat->adj_sqr_r);
-
-	/* Standard Error */
-	dao_set_cell_float (dao, 1, 6, gnm_sqrt (regression_stat->var));
+	if (dao_cell_is_visible (dao, 1, 7))
+		expr_n = make_cellref (0, 1);
+	else
+		expr_n = gnm_expr_new_funcall3 (fd_sum,
+						gnm_expr_new_constant (value_new_int (xdim)),
+						gnm_expr_new_funcall3 (fd_index, 
+								       gnm_expr_copy (expr_linest),
+								       gnm_expr_new_constant (value_new_int (4)),
+								       gnm_expr_new_constant (value_new_int (2))),
+						gnm_expr_new_constant (value_new_int (1)));
+	
+	dao_set_cell_expr (dao, 1, 6, gnm_expr_new_binary
+			   (gnm_expr_new_constant (value_new_int (1)),
+			    GNM_EXPR_OP_SUB,
+			    gnm_expr_new_binary
+			    (gnm_expr_new_binary
+			     (gnm_expr_new_binary 
+			      (gnm_expr_copy (expr_n),
+			       GNM_EXPR_OP_SUB,
+			       gnm_expr_new_constant (value_new_int (1))),
+			      GNM_EXPR_OP_DIV,
+			      gnm_expr_new_binary 
+			      (expr_n,
+			       GNM_EXPR_OP_SUB,
+			       gnm_expr_new_constant (value_new_int (xdim + (info->intercept?1:0))))),
+			     GNM_EXPR_OP_MULT,
+			     gnm_expr_new_binary
+			     (gnm_expr_new_constant (value_new_int (1)),
+			      GNM_EXPR_OP_SUB,
+			      make_cellref (0, -2)))));
 
 	/* Observations */
-	dao_set_cell_float (dao, 1, 7, y_data->data->len);
+
+	if (dao_cell_is_visible (dao, 1, 13)) 
+		dao_set_cell_expr (dao, 1, 7, 
+				   gnm_expr_new_funcall2 (fd_sum,
+							  make_cellref (0, 6),
+							  gnm_expr_new_constant (value_new_int (info->intercept?1:0))));
+	else if (dao_cell_is_visible (dao, 1, 12)) 
+		dao_set_cell_expr (dao, 1, 7, 
+				   gnm_expr_new_funcall3 (fd_sum,
+							  make_cellref (0, 4),
+							  make_cellref (0, 5),
+							  gnm_expr_new_constant (value_new_int (info->intercept?1:0))));
+	else 
+		dao_set_cell_expr (dao, 1, 7, 
+				   gnm_expr_new_funcall3 (fd_sum,
+							  gnm_expr_new_constant (value_new_int (xdim)),
+							  gnm_expr_new_funcall3 (fd_index, 
+										 gnm_expr_copy (expr_linest),
+										 gnm_expr_new_constant (value_new_int (4)),
+										 gnm_expr_new_constant (value_new_int (2))),
+							  gnm_expr_new_constant (value_new_int (info->intercept?1:0))));
+	
+
 
 	/* Regression / df */
-	dao_set_cell_float (dao, 1, 11, regression_stat->df_reg);
+
+	dao_set_cell_int (dao, 1, 11, xdim);
 
 	/* Residual / df */
-	dao_set_cell_float (dao, 1, 12, regression_stat->df_resid);
+	dao_set_cell_array_expr (dao, 1, 12, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (4)),
+							gnm_expr_new_constant (value_new_int (2))));
+
 
 	/* Total / df */
-	dao_set_cell_float (dao, 1, 13, regression_stat->df_total);
+	expr_sum = gnm_expr_new_binary (make_cellref (0, -2),
+				       GNM_EXPR_OP_ADD,
+				       make_cellref (0, -1));
+	dao_set_cell_expr (dao, 1, 13, gnm_expr_copy (expr_sum));
+
+	/* Regression / SS */
+	dao_set_cell_array_expr (dao, 2, 11, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (5)),
+							gnm_expr_new_constant (value_new_int (1))));
 
 	/* Residual / SS */
-	dao_set_cell_float (dao, 2, 12, regression_stat->ss_resid);
+	dao_set_cell_array_expr (dao, 2, 12, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (5)),
+							gnm_expr_new_constant (value_new_int (2))));
 
-	/* Total / SS */
-	dao_set_cell_float (dao, 2, 13, regression_stat->ss_total);
 
-	/* Regression / SS */
-	dao_set_cell_float (dao, 2, 11, regression_stat->ss_reg);
+	/* Total / SS */
+	dao_set_cell_expr (dao, 2, 13, expr_sum);
 
+    
 	/* Regression / MS */
-	dao_set_cell_float (dao, 3, 11, regression_stat->ms_reg);
+	expr_ms = gnm_expr_new_binary (make_cellref (-1, 0),
+				       GNM_EXPR_OP_DIV,
+				       make_cellref (-2, 0));
+	dao_set_cell_expr (dao, 3, 11, gnm_expr_copy (expr_ms));
 
 	/* Residual / MS */
-	dao_set_cell_float (dao, 3, 12, regression_stat->ms_resid);
+	dao_set_cell_expr (dao, 3, 12, expr_ms);
+	
 
 	/* F */
-	dao_set_cell_float (dao, 4, 11, regression_stat->F);
+	dao_set_cell_array_expr (dao, 4, 11, 
+				 gnm_expr_new_funcall3 (fd_index, 
+							gnm_expr_copy (expr_linest),
+							gnm_expr_new_constant (value_new_int (4)),
+							gnm_expr_new_constant (value_new_int (1))));
 
 	/* Significance of F */
-	dao_set_cell_float (dao, 5, 11, pf (regression_stat->F,
-					regression_stat->df_reg,
-					regression_stat->df_resid,
-					FALSE, FALSE));
 
-	/* Intercept / Coefficient */
-	dao_set_cell_float (dao, 1, 16, res[0]);
+	if (dao_cell_is_visible (dao, 1, 12))
+		dao_set_cell_expr (dao, 5, 11, gnm_expr_new_funcall3 (fd_fdist,
+								      make_cellref (-1, 0),
+								      make_cellref (-4, 0),
+								      make_cellref (-4, 1)));
+	else
+		dao_set_cell_expr (dao, 5, 11, gnm_expr_new_funcall3 (fd_fdist,
+								      make_cellref (-1, 0),
+								      make_cellref (-4, 0),
+								      gnm_expr_new_funcall3 
+								      (fd_index, 
+								       gnm_expr_copy (expr_linest),
+								       gnm_expr_new_constant (value_new_int (4)),
+								       gnm_expr_new_constant (value_new_int (2)))));
+	
+
+	/* Intercept */
 
-	if (!info->intercept)
+
+	expr_tstat = gnm_expr_new_binary (make_cellref (-2, 0),
+				       GNM_EXPR_OP_DIV,
+				       make_cellref (-1, 0));
+	expr_df = dao_get_cellref (dao, 1, 12);
+	expr_pvalue = gnm_expr_new_funcall3 (fd_tdist, make_cellref (-1, 0),
+					     gnm_expr_copy (expr_df),
+					     gnm_expr_new_constant (value_new_int (2)));
+	expr_lower = gnm_expr_new_binary (make_cellref (-4, 0),
+				      GNM_EXPR_OP_SUB,
+				      gnm_expr_new_binary (make_cellref (-3, 0),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_funcall2 
+							   (fd_tinv,
+							    gnm_expr_new_binary 
+							    (gnm_expr_new_constant (value_new_float (1.0)),
+							     GNM_EXPR_OP_SUB,
+							     gnm_expr_copy (expr_confidence)),
+							    gnm_expr_copy (expr_df))));
+	expr_upper = gnm_expr_new_binary (make_cellref (-5, 0),
+				      GNM_EXPR_OP_ADD,
+				      gnm_expr_new_binary (make_cellref (-4, 0),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_funcall2 
+							   (fd_tinv,
+							    gnm_expr_new_binary 
+							    (gnm_expr_new_constant (value_new_float (1.0)),
+							     GNM_EXPR_OP_SUB,
+							     expr_confidence),
+							    expr_df)));
+
+
+	/* Intercept */
+
+	if (!info->intercept) {
+		dao_set_cell_int (dao, 1, 16, 0);
 		for (i = 2; i <= 6; i++)
 			dao_set_cell_na (dao, i, 16);
+	} else {
+		dao_set_cell_array_expr (dao, 1, 16, 
+					 gnm_expr_new_funcall3 
+					 (fd_index, 
+					  gnm_expr_copy (expr_linest),
+					  gnm_expr_new_constant (value_new_int (1)),
+					  gnm_expr_new_constant (value_new_int (xdim+1))));
+		dao_set_cell_array_expr (dao, 2, 16, 
+					 gnm_expr_new_funcall3 
+					 (fd_index, 
+					  gnm_expr_copy (expr_linest),
+					  gnm_expr_new_constant (value_new_int (2)),
+					  gnm_expr_new_constant (value_new_int (xdim+1))));
+		dao_set_cell_expr (dao, 3, 16, gnm_expr_copy (expr_tstat));
+		dao_set_cell_expr (dao, 4, 16, gnm_expr_copy (expr_pvalue));
+		dao_set_cell_expr (dao, 5, 16, gnm_expr_copy (expr_lower));
+		dao_set_cell_expr (dao, 6, 16, gnm_expr_copy (expr_upper));
+	}
 
-	/* i==-1 is for intercept, i==0... is for slopes.  */
-	for (i = -info->intercept; i < xdim; i++) {
-		gnm_float this_res = res[i + 1];
-		/*
-		 * With no intercept se[0] is for the first slope variable;
-		 * with intercept, se[1] is the first slope se
-		 */
-		gnm_float this_se = regression_stat->se[info->intercept + i];
-		gnm_float this_tval = regression_stat->t[info->intercept + i];
-		gnm_float t, P;
+	/* Coefficients */
 
-		/* Coefficient */
-		dao_set_cell_float (dao, 1, 17 + i, this_res);
+	dao->offset_row += 17;
 
-		/* Standard Error */
-		dao_set_cell_float (dao, 2, 17 + i, this_se);
+	for (i = 0; i < xdim; i++) {
+		if (!info->base.labels)
+			dao_set_cell_printf (dao, 0, i,
+					     (info->group_by == GROUPED_BY_ROW) ?  
+					     _("Row %i") :  _("Column %i"), i + 1);
+		
+		dao_set_cell_array_expr (dao, 1, i, 
+					 gnm_expr_new_funcall3 
+					 (fd_index, 
+					  gnm_expr_copy (expr_linest),
+					  gnm_expr_new_constant (value_new_int (1)),
+					  gnm_expr_new_constant (value_new_int (xdim - i))));
+		dao_set_cell_array_expr (dao, 2, i, 
+					 gnm_expr_new_funcall3 
+					 (fd_index, 
+					  gnm_expr_copy (expr_linest),
+					  gnm_expr_new_constant (value_new_int (2)),
+					  gnm_expr_new_constant (value_new_int (xdim - i))));		
+		dao_set_cell_expr (dao, 3, i, gnm_expr_copy (expr_tstat));
+		dao_set_cell_expr (dao, 4, i, gnm_expr_copy (expr_pvalue));
+		dao_set_cell_expr (dao, 5, i, gnm_expr_copy (expr_lower));
+		dao_set_cell_expr (dao, 6, i, gnm_expr_copy (expr_upper));
+	}
+
+	
+	gnm_expr_free (expr_linest);
+	gnm_expr_free (expr_tstat);
+	gnm_expr_free (expr_pvalue);
+	gnm_expr_free (expr_lower);
+	gnm_expr_free (expr_upper);
 
-		/* t Stat */
-		dao_set_cell_float (dao, 3, 17 + i, this_tval);
+	value_release (val_1);
+	value_release (val_2);
+	if (val_1_cp)
+		value_release (val_1_cp);
+	if (val_2_cp)
+		value_release (val_2_cp);
+
+	gnm_func_unref (fd_linest);
+	gnm_func_unref (fd_index);
+	gnm_func_unref (fd_fdist);
+	gnm_func_unref (fd_sum);
+	gnm_func_unref (fd_sqrt);
+	gnm_func_unref (fd_tdist);
+	gnm_func_unref (fd_tinv);
+	gnm_func_unref (fd_transpose);
 
-		/* P values */
-		P = gnm_finite (this_tval)
-			? 2 * pt (gnm_abs (this_tval), regression_stat->df_resid, FALSE, FALSE)
-			: 0;
-		dao_set_cell_float (dao, 4, 17 + i, P);
-
-		t = (this_se == 0)
-			? 0
-			: qt (info->alpha / 2, regression_stat->df_resid,
-			      FALSE, FALSE);
-
-		/* Lower 95% */
-		dao_set_cell_float (dao, 5, 17 + i, this_res - t * this_se);
-
-		/* Upper 95% */
-		dao_set_cell_float (dao, 6, 17 + i, this_res + t * this_se);
-	}
-
-	gnm_regression_stat_destroy (regression_stat);
-	destroy_data_set (y_data);
-	destroy_data_set_list (x_data);
-	g_free (xss);
-	g_free (res);
-
-	if (regerr == REG_near_singular_good)
-		gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->base.wbc),
-			_("Two or more of the independent variables "
-			  "are nearly linearly\ndependent.  Treat the "
-			  "regression result with great care!"));
+	dao_redraw_respan (dao);
 
 	return FALSE;
 }
@@ -3149,19 +3283,16 @@
 		return (dao_command_descriptor (dao, _("Regression (%s)"), result)
 			== NULL);
 	case TOOL_ENGINE_UPDATE_DAO:
-		prepare_input_range (&info->base.input, info->base.group_by);
-		if (!gnm_check_input_range_list_homogeneity (info->base.input)) {
-			info->base.err = analysis_tools_REG_invalid_dimensions;
-			return TRUE;
-		}
-		dao_adjust (dao, 7, 17 + g_slist_length (info->base.input));
+	{
+		gint xdim = calculate_xdim (info->base.range_1, info->group_by);
+
+		dao_adjust (dao, 7, 17 + xdim);
 		return FALSE;
+	}
 	case TOOL_ENGINE_CLEAN_UP:
-		value_release (info->y_input);
-		info->y_input = NULL;
-		return analysis_tool_generic_clean (dao, specs);
+		return analysis_tool_ftest_clean (dao, specs);
 	case TOOL_ENGINE_LAST_VALIDITY_CHECK:
-		return analysis_tool_regression_engine_last_check (dao, specs);
+		return FALSE;
 	case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
 		dao_prepare_output (NULL, dao, _("Regression"));
 		return FALSE;

Modified: trunk/src/tools/analysis-tools.h
==============================================================================
--- trunk/src/tools/analysis-tools.h	(original)
+++ trunk/src/tools/analysis-tools.h	Mon Sep  8 00:28:03 2008
@@ -24,8 +24,7 @@
 	analysis_tools_missing_data,
 	analysis_tools_too_few_cols,
 	analysis_tools_too_few_rows,
-	analysis_tools_replication_invalid,
-	analysis_tools_REG_invalid_dimensions
+	analysis_tools_replication_invalid
 } analysis_tools_error_code_t;
 
 
@@ -143,18 +142,6 @@
 				       analysis_tool_engine_t selector, gpointer result);
 
 
-/****************  Regression  ********************/
-
-typedef struct {
-	analysis_tools_data_generic_t base;
-	GnmValue      *y_input;
-	gnm_float alpha;
-	gint       intercept;
-
-} analysis_tools_data_regression_t;
-
-gboolean analysis_tool_regression_engine (data_analysis_output_t *dao, gpointer specs,
-					   analysis_tool_engine_t selector, gpointer result);
 
 
 /********************************************************************/
@@ -175,6 +162,16 @@
 gboolean analysis_tool_ftest_engine (data_analysis_output_t *dao, gpointer specs,
 				     analysis_tool_engine_t selector, gpointer result);
 
+/****************  Regression  ********************/
+
+typedef struct {
+	analysis_tools_data_ftest_t base;
+	gint       intercept;
+	group_by_t group_by;
+} analysis_tools_data_regression_t;
+
+gboolean analysis_tool_regression_engine (data_analysis_output_t *dao, gpointer specs,
+					   analysis_tool_engine_t selector, gpointer result);
 /*********************** TTest paired *****************/
 
 typedef struct {

Modified: trunk/src/tools/dao.c
==============================================================================
--- trunk/src/tools/dao.c	(original)
+++ trunk/src/tools/dao.c	Mon Sep  8 00:28:03 2008
@@ -307,37 +307,63 @@
  *
  */
 void 
-dao_set_cell_array_expr (data_analysis_output_t *dao, int col, int row,
-			 GnmExpr const *expr)
+dao_set_array_expr (data_analysis_output_t *dao,
+		    int col, int row, int cols, int rows,
+		    GnmExpr const *expr)
 {
 	GnmExprTop const *texpr;
+	int col_end;
+	int row_end;
 
 	col += dao->offset_col;
 	row += dao->offset_row;
+	col_end = col + cols - 1;
+	row_end = row + rows - 1;
 
 	/* Check that the output is in the given range, but allow singletons
 	 * to expand
 	 */
-	if (dao->type == RangeOutput &&
-	    (dao->cols > 1 || dao->rows > 1) &&
-	    (col >= dao->cols || row >= dao->rows)) {
-		gnm_expr_free (expr);
-	        return;
+	if (dao->type == RangeOutput && (dao->cols > 1 || dao->rows > 1)) {
+		if (col >= dao->cols || row >= dao->rows) {
+			gnm_expr_free (expr);
+			return;
+		}
+		if (col_end >= dao->cols)
+			col_end = dao->cols - 1;
+		if (row_end >= dao->rows)
+			row_end = dao->rows - 1;
 	}
 
 	col += dao->start_col;
 	row += dao->start_row;
-	if (col >= gnm_sheet_get_max_cols (dao->sheet) || row >= gnm_sheet_get_max_rows (dao->sheet)) {
+	col_end += dao->start_col;
+	row_end += dao->start_row;
+	if (col >= gnm_sheet_get_max_cols (dao->sheet) 
+	    || row >= gnm_sheet_get_max_rows (dao->sheet)) {
 		gnm_expr_free (expr);
 		return;
 	}
+	if (col_end >= gnm_sheet_get_max_cols (dao->sheet))
+		col_end = gnm_sheet_get_max_cols (dao->sheet) - 1;
+	if (row_end >= gnm_sheet_get_max_rows (dao->sheet))
+		row_end = gnm_sheet_get_max_rows (dao->sheet) - 1;
 
 	texpr = gnm_expr_top_new (expr);
 	gnm_cell_set_array_formula (dao->sheet, 
-				    col, row, col, row,
+				    col, row, 
+				    col_end, row_end,
 				    texpr);
 }
-
+/*
+ * dao_set_cell_array_expr absorbs the reference for the expr.
+ *
+ */
+void 
+dao_set_cell_array_expr (data_analysis_output_t *dao, int col, int row,
+			 GnmExpr const *expr)
+{
+	dao_set_array_expr (dao, col, row, 1, 1, expr);
+}
 
 /*
  * dao_set_cell_expr absorbs the reference for the expr.
@@ -809,6 +835,32 @@
 }
 
 /**
+ * dao_set_format:
+ * @dao:
+ * @col1:
+ * @row1:
+ * @col2:
+ * @row2:
+ * @format:
+ *
+ * set the given cell range to given format
+ *
+ *
+ **/
+void
+dao_set_format (data_analysis_output_t *dao, int col1, int row1,
+		int col2, int row2,
+		char const * format)
+{
+	GnmStyle *mstyle;
+
+	mstyle = gnm_style_new ();
+	gnm_style_set_format_text (mstyle, format);
+	dao_set_style (dao, col1, row1,
+		       col2, row2, mstyle);
+}
+
+/**
  * dao_set_colors:
  * @dao:
  * @col1:
@@ -1058,3 +1110,17 @@
 	dao_convert_to_values (dao);
 	sheet_redraw_range (dao->sheet, &r);
 }
+
+
+GnmExpr const  *
+dao_get_cellref (data_analysis_output_t *dao, int dx, int dy)
+{
+	GnmCellRef r;
+	r.sheet = dao->sheet;
+	r.col = dx + dao->start_col + dao->offset_col;
+	r.col_relative = FALSE;
+	r.row = dy + dao->start_row + dao->offset_row;
+	r.row_relative = FALSE;
+	return gnm_expr_new_cellref (&r);
+}
+

Modified: trunk/src/tools/dao.h
==============================================================================
--- trunk/src/tools/dao.h	(original)
+++ trunk/src/tools/dao.h	Mon Sep  8 00:28:03 2008
@@ -69,6 +69,8 @@
 			       int col2, int row2);
 void dao_set_date             (data_analysis_output_t *dao, int col1, int row1,
 			       int col2, int row2);
+void dao_set_format             (data_analysis_output_t *dao, int col1, int row1,
+				 int col2, int row2, char const *format);
 
 void dao_set_colors (data_analysis_output_t *dao, int col1, int row1,
 		     int col2, int row2,
@@ -87,6 +89,9 @@
 			       GnmExpr const *expr);
 void dao_set_cell_array_expr (data_analysis_output_t *dao, int col, int row,
 			      GnmExpr const *expr);
+void dao_set_array_expr (data_analysis_output_t *dao,
+			 int col, int row,  int cols, int rows,
+			 GnmExpr const *expr);
 void dao_set_cell_float       (data_analysis_output_t *dao,
 			       int col, int row, gnm_float v);
 void dao_set_cell_int         (data_analysis_output_t *dao,
@@ -121,6 +126,7 @@
 void dao_convert_to_values (data_analysis_output_t *dao);
 void dao_redraw_respan (data_analysis_output_t *dao);
 
+GnmExpr const *dao_get_cellref (data_analysis_output_t *dao, int dx, int dy);
 
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]