From: John Darrington Date: Mon, 24 Nov 2008 13:16:02 +0000 (+0900) Subject: Merge branch 'rewrite-sheet' of ssh://jmd@git.sv.gnu.org/srv/git/pspp into rewrite... X-Git-Tag: v0.7.1~118 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddd7c113f3e50c8d87f6a677856799d05a1f40c7;hp=bfa3bb62acfb1496a028c4baa800b2d2c5b543f5;p=pspp-builds.git Merge branch 'rewrite-sheet' of ssh://jmd@git.sv.gnu.org/srv/git/pspp into rewrite-sheet Conflicts: lib/gtksheet/gtksheet.c --- diff --git a/examples/grid.sps b/examples/grid.sps index cfaa80a6..ea7f9d74 100644 --- a/examples/grid.sps +++ b/examples/grid.sps @@ -3,7 +3,7 @@ COMMENT -*-pspp-*- . COMMENT This program is useful for testing the behaviour of the Data and Variable Sheets. input program. - vector var(500 F8.3). +vector var(500 F8.3). loop #c = 1 to 1000. loop #v = 1 to 500. compute var(#v) = #v + #c / 1000. @@ -13,6 +13,8 @@ input program. end file. end input program. +variable label var1 'First variable' var2 'Second variable' var3 'Third variable'. + save outfile='grid.sav'. execute. diff --git a/lib/gtksheet/automake.mk b/lib/gtksheet/automake.mk index bba6becc..c5999498 100644 --- a/lib/gtksheet/automake.mk +++ b/lib/gtksheet/automake.mk @@ -6,16 +6,10 @@ lib_gtksheet_libgtksheet_a_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1 lib_gtksheet_libgtksheet_a_SOURCES = \ - lib/gtksheet/gsheet-column-iface.c \ - lib/gtksheet/gsheet-column-iface.h \ - lib/gtksheet/gsheet-hetero-column.c \ - lib/gtksheet/gsheet-hetero-column.h \ lib/gtksheet/gsheetmodel.c \ lib/gtksheet/gsheetmodel.h \ lib/gtksheet/gsheet-row-iface.c \ lib/gtksheet/gsheet-row-iface.h \ - lib/gtksheet/gsheet-uniform-column.c \ - lib/gtksheet/gsheet-uniform-column.h \ lib/gtksheet/gsheet-uniform-row.c \ lib/gtksheet/gsheet-uniform-row.h \ lib/gtksheet/gtkextrafeatures.h \ @@ -27,7 +21,10 @@ lib_gtksheet_libgtksheet_a_SOURCES = \ lib/gtksheet/gtksheet.c \ lib/gtksheet/gtksheet.h \ lib/gtksheet/gtkxpaned.c \ - lib/gtksheet/gtkxpaned.h + lib/gtksheet/gtkxpaned.h \ + lib/gtksheet/psppire-axis.c \ + lib/gtksheet/psppire-axis.h + EXTRA_DIST += lib/gtksheet/OChangeLog \ lib/gtksheet/README diff --git a/lib/gtksheet/gsheet-column-iface.c b/lib/gtksheet/gsheet-column-iface.c deleted file mode 100644 index 56dcbca8..00000000 --- a/lib/gtksheet/gsheet-column-iface.c +++ /dev/null @@ -1,214 +0,0 @@ -/* GSheetColumn --- an abstract model of the column geometry of a - GSheet widget. - - * Copyright (C) 2006 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include -#include -#include -#include -#include -#include "gsheet-column-iface.h" -#include "gtkextra-marshal.h" -#include "gtkextra-sheet.h" - -enum { - COLUMNS_CHANGED, - LAST_SIGNAL -}; - -static guint sheet_column_signals[LAST_SIGNAL]; - -static void g_sheet_column_base_init (gpointer g_class); - -GType -g_sheet_column_get_type (void) -{ - static GType sheet_column_type = 0; - - if (! sheet_column_type) - { - static const GTypeInfo sheet_column_info = - - { - sizeof (GSheetColumnIface), /* class_size */ - g_sheet_column_base_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - sheet_column_type = - g_type_register_static (G_TYPE_INTERFACE, "GSheetColumn", - &sheet_column_info, 0); - - g_assert (sheet_column_type); - - g_type_interface_add_prerequisite (sheet_column_type, G_TYPE_OBJECT); - } - - return sheet_column_type; -} - - -static void -g_sheet_column_base_init (gpointer g_class) -{ - static gboolean initialized = FALSE; - - if (! initialized) - { - - sheet_column_signals[COLUMNS_CHANGED] = - g_signal_new ("columns_changed", - G_TYPE_SHEET_COLUMN, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GSheetColumnIface, columns_changed), - NULL, NULL, - gtkextra_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - - initialized = TRUE; - } -} - - -void -g_sheet_column_set_width (GSheetColumn *column, glong col, gint size) -{ - g_return_if_fail (G_IS_SHEET_COLUMN (column)); - - if ((G_SHEET_COLUMN_GET_IFACE (column)->set_width) ) - (G_SHEET_COLUMN_GET_IFACE (column)->set_width) (column, col, size); -} - - -gint -g_sheet_column_get_width (const GSheetColumn *column, glong col) -{ - g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1); - - g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_width); - - return (G_SHEET_COLUMN_GET_IFACE (column)->get_width) (column, col); -} - - - -gboolean -g_sheet_column_get_sensitivity (const GSheetColumn *column, - glong col) -{ - g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE); - - g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity); - - return (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity) (column, - col); - -} - - -GtkSheetButton * -g_sheet_column_get_button (const GSheetColumn *column, - glong col) -{ - GtkSheetButton *button = gtk_sheet_button_new (); - - GSheetColumnIface *iface = G_SHEET_COLUMN_GET_IFACE (column); - - g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE); - - if ( iface->get_button_label) - button->label = iface->get_button_label (column, col); - - return button; -} - -GtkJustification -g_sheet_column_get_justification (const GSheetColumn *column, - glong col) -{ - g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE); - - g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_justification); - - return (G_SHEET_COLUMN_GET_IFACE (column)->get_justification) (column, col); -} - -gchar * -g_sheet_column_get_subtitle (const GSheetColumn *column, glong col) -{ - g_return_val_if_fail (G_IS_SHEET_COLUMN (column), NULL); - - if ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_subtitle) - return NULL; - - return (G_SHEET_COLUMN_GET_IFACE (column)->get_subtitle) (column, col); -} - - - -glong -g_sheet_column_get_column_count (const GSheetColumn *geo) -{ - g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1); - - g_assert ( G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count); - - return (G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count) (geo); -} - -gint -g_sheet_column_start_pixel (const GSheetColumn *geo, glong col) -{ - gint i; - gint start_pixel = 0; - - g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1); - g_return_val_if_fail (col <= g_sheet_column_get_column_count (geo), -1); - - for (i = 0; i < col; ++i) - { - start_pixel += g_sheet_column_get_width (geo, i); - } - - return start_pixel; -} - - - -void -g_sheet_column_columns_changed (GSheetColumn *geo, - glong first, glong n_columns) -{ - g_return_if_fail (G_IS_SHEET_COLUMN (geo)); - - g_signal_emit (geo, sheet_column_signals[COLUMNS_CHANGED], 0, - first, n_columns); -} - diff --git a/lib/gtksheet/gsheet-column-iface.h b/lib/gtksheet/gsheet-column-iface.h deleted file mode 100644 index 34ccbf21..00000000 --- a/lib/gtksheet/gsheet-column-iface.h +++ /dev/null @@ -1,104 +0,0 @@ -/* GSheetColumn --- an abstract model of the column geometry of a - * GSheet widget. - * Copyright (C) 2006 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GSHEET_COLUMN_IFACE_H -#define __GSHEET_COLUMN_IFACE_H - -#include -#include -#include - -#include "gtkextra-sheet.h" - - -G_BEGIN_DECLS - -#define G_TYPE_SHEET_COLUMN (g_sheet_column_get_type ()) -#define G_SHEET_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SHEET_COLUMN, GSheetColumn)) -#define G_IS_SHEET_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SHEET_COLUMN)) -#define G_SHEET_COLUMN_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SHEET_COLUMN, GSheetColumnIface)) - - -typedef struct _GSheetColumn GSheetColumn; -typedef struct _GSheetColumnIface GSheetColumnIface; -struct _GSheetColumnIface -{ - GTypeInterface g_iface; - - - /* Signals */ - void (* columns_changed) (GSheetColumn *geo, - glong col, glong n_columns); - - /* Virtual Table */ - gint (* get_width) (const GSheetColumn *gcolumn, glong col); - void (* set_width) (GSheetColumn *gcolumn, glong col, gint width); - - gboolean (* get_sensitivity) (const GSheetColumn *gcolumn, glong col); - const GtkSheetButton * (* get_button) (const GSheetColumn *gcolumn, glong col); - GtkJustification (* get_justification) (const GSheetColumn *gcolumn, glong col); - - glong (* get_column_count) (const GSheetColumn *geo); - - - GtkStateType (*get_button_state)(const GSheetColumn *geo, glong col); - gchar * (*get_button_label)(const GSheetColumn *geo, glong col); - gchar * (*get_subtitle)(const GSheetColumn *geo, glong col); - - gboolean (*get_button_visibility)(const GSheetColumn *geo, - glong col); - - GtkJustification * (*get_button_justification)(const GSheetColumn *geo, - glong col); -}; - - -GType g_sheet_column_get_type (void) G_GNUC_CONST; - - -gint g_sheet_column_get_width (const GSheetColumn *gcolumn, - glong col); - - -void g_sheet_column_set_width (GSheetColumn *gcolumn, - glong col, gint size); - - -gboolean g_sheet_column_get_sensitivity (const GSheetColumn *gcolumn, - glong col); - - -GtkSheetButton *g_sheet_column_get_button (const GSheetColumn *gcolumn, - glong col); - -gchar *g_sheet_column_get_subtitle (const GSheetColumn *, glong); - -GtkJustification g_sheet_column_get_justification (const GSheetColumn *gcolumn, glong col); - - -glong g_sheet_column_get_column_count (const GSheetColumn *geo); - -gint g_sheet_column_start_pixel (const GSheetColumn *geo, glong col); - -void g_sheet_column_columns_changed (GSheetColumn *geo, - glong first, glong n_columns); - -G_END_DECLS - -#endif /* __G_SHEET_COLUMN_IFACE_H__ */ diff --git a/lib/gtksheet/gsheet-hetero-column.c b/lib/gtksheet/gsheet-hetero-column.c deleted file mode 100644 index 42b1035f..00000000 --- a/lib/gtksheet/gsheet-hetero-column.c +++ /dev/null @@ -1,228 +0,0 @@ -/* gsheet-hetero-column.c - * PSPPIRE --- A Graphical User Interface for PSPP - * Copyright (C) 2006 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#include "gsheet-column-iface.h" -#include "gsheet-hetero-column.h" -#include - - -static void g_sheet_hetero_column_init (GSheetHeteroColumn *hg); -static void g_sheet_hetero_column_class_init (GSheetHeteroColumnClass *class); -static void g_sheet_hetero_column_finalize (GObject *object); - -static void g_sheet_column_init (GSheetColumnIface *iface); - - -static GObjectClass *parent_class = NULL; - -GType -g_sheet_hetero_column_get_type (void) -{ - static GType hetero_column_type = 0; - - if (!hetero_column_type) - { - static const GTypeInfo hetero_column_info = - { - sizeof (GSheetHeteroColumnClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) g_sheet_hetero_column_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GSheetHeteroColumn), - 0, - (GInstanceInitFunc) g_sheet_hetero_column_init, - }; - - static const GInterfaceInfo column_info = - { - (GInterfaceInitFunc) g_sheet_column_init, - NULL, - NULL - }; - - hetero_column_type = - g_type_register_static (G_TYPE_OBJECT, "g_sheet_hetero_column", - &hetero_column_info, 0); - - g_type_add_interface_static (hetero_column_type, - G_TYPE_SHEET_COLUMN, - &column_info); - } - - return hetero_column_type; -} - - -static GtkSheetButton default_button; - - - -/** - * g_sheet_hetero_column_new: - * @width: The size of columns in this hetero column - * - * Return value: a new #g_sheet_hetero_column - **/ -GObject * -g_sheet_hetero_column_new (gint default_width, gint n_columns) -{ - gint i; - GSheetHeteroColumn *hg; - GObject *retval; - - retval = g_object_new (G_TYPE_SHEET_HETERO_COLUMN, NULL); - - hg = G_SHEET_HETERO_COLUMN (retval); - hg->n_columns = n_columns; - hg->default_width = default_width; - hg->col = g_new0 (struct GSheetHeteroColumnUnit, n_columns); - - for (i = 0 ; i < hg->n_columns; ++i ) - { - hg->col[i].button = default_button; - } - - return retval; -} - -static gint -g_sheet_hetero_column_get_width (const GSheetColumn *geom, glong i) -{ - GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom); - - g_return_val_if_fail (i < hg->n_columns, -1); - - return hg->col[i].width; -} - -static gboolean -g_sheet_hetero_column_get_sensitivity (const GSheetColumn *geom, glong u) -{ - return TRUE; -} - - -static gchar * -g_sheet_hetero_column_get_button_label (const GSheetColumn *geom, glong u) -{ - GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom); - - return g_locale_to_utf8 (hg->col[u].button.label, -1, 0, 0, 0); -} - - -static GtkJustification -g_sheet_hetero_column_get_justification (const GSheetColumn *geom, glong u) -{ - return GTK_JUSTIFY_LEFT; -} - - - -static glong -g_sheet_hetero_column_get_column_count (const GSheetColumn *geom) -{ - GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom); - - return hg->n_columns; -} - -static void -g_sheet_hetero_column_class_init (GSheetHeteroColumnClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GObjectClass*) class; - - object_class->finalize = g_sheet_hetero_column_finalize; - - default_button.label=NULL; - default_button.state=GTK_STATE_NORMAL; - default_button.justification=GTK_JUSTIFY_CENTER; - default_button.label_visible = TRUE; -} - - -static void -g_sheet_hetero_column_init (GSheetHeteroColumn *o) -{ -} - -static void -g_sheet_hetero_column_finalize (GObject *object) -{ - GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (object); - - g_free (hg->col); -} - -static void -hetero_column_set_width (GSheetColumn *geo, glong i, gint size) -{ - GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geo); - - g_return_if_fail (i < hg->n_columns); - - hg->col[i].width = size; -} - - - -static void -g_sheet_column_init (GSheetColumnIface *iface) -{ - iface->get_width = g_sheet_hetero_column_get_width ; - iface->set_width = hetero_column_set_width ; - iface->get_sensitivity = g_sheet_hetero_column_get_sensitivity ; - iface->get_justification = g_sheet_hetero_column_get_justification; - iface->get_column_count = g_sheet_hetero_column_get_column_count; - - iface->get_button_label = g_sheet_hetero_column_get_button_label; -} - - -void -g_sheet_hetero_column_set_button_label (GSheetHeteroColumn *geo, - glong i, const gchar *label) -{ - g_return_if_fail (i < geo->n_columns); - - g_free (geo->col[i].button.label); - geo->col[i].button.label = g_malloc (strlen (label) + 1); - - g_stpcpy (geo->col[i].button.label, label); -} - - - - -void -g_sheet_hetero_column_set_width (GSheetHeteroColumn *geo, glong i, gint size) -{ - GSheetColumn *iface = G_SHEET_COLUMN (geo); - - hetero_column_set_width (iface, i, size); -} - - - diff --git a/lib/gtksheet/gsheet-hetero-column.h b/lib/gtksheet/gsheet-hetero-column.h deleted file mode 100644 index 9b19c1f3..00000000 --- a/lib/gtksheet/gsheet-hetero-column.h +++ /dev/null @@ -1,87 +0,0 @@ -/* GtkSheet widget for Gtk+. - * Copyright (C) 2006 Free Software Foundation - - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __G_SHEET_HETERO_COLUMN_H__ -#define __G_SHEET_HETERO_COLUMN_H__ - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define G_TYPE_SHEET_HETERO_COLUMN (g_sheet_hetero_column_get_type ()) - -#define G_SHEET_HETERO_COLUMN(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, G_TYPE_SHEET_HETERO_COLUMN, GSheetHeteroColumn ) -#define G_SHEET_HETERO_COLUMN_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, g_sheet_hetero_column_get_type (), GSheetHeteroColumnClass) -#define G_IS_SHEET_HETERO_COLUMN(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_SHEET_HETERO_COLUMN) - - - struct GSheetHeteroColumnUnit - { - GtkSheetButton button; - - gint width; - gboolean is_sensitive; - }; - - - struct _GSheetHeteroColumn{ - GObject parent; - - gint n_columns; - gint default_width; - - struct GSheetHeteroColumnUnit *col; - - }; - - struct _GSheetHeteroColumnClass - { - GObjectClass parent_class; - }; - - - - - /* create a new column */ - GObject * g_sheet_hetero_column_new (gint default_width, gint n_columns); - - GType g_sheet_hetero_column_get_type (void); - - - typedef struct _GSheetHeteroColumn GSheetHeteroColumn; - typedef struct _GSheetHeteroColumnClass GSheetHeteroColumnClass; - - - void g_sheet_hetero_column_set_button_label (GSheetHeteroColumn *geo, - glong i, const gchar *label); - - void g_sheet_hetero_column_set_width (GSheetHeteroColumn *geo, - glong i, gint size); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __G_SHEET_HETERO_COLUMN_H__ */ - - diff --git a/lib/gtksheet/gsheet-uniform-column.c b/lib/gtksheet/gsheet-uniform-column.c deleted file mode 100644 index c0f6732a..00000000 --- a/lib/gtksheet/gsheet-uniform-column.c +++ /dev/null @@ -1,173 +0,0 @@ -/* gsheet-uniform-column.c - * - * PSPPIRE --- A Graphical User Interface for PSPP - * Copyright (C) 2006 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "gsheet-column-iface.h" -#include "gsheet-uniform-column.h" - - -static void g_sheet_uniform_column_init (GSheetUniformColumn *ug); -static void g_sheet_uniform_column_class_init (GSheetUniformColumnClass *class); -static void g_sheet_uniform_column_finalize (GObject *object); - -static void g_sheet_column_init (GSheetColumnIface *iface); - - -static GObjectClass *parent_class = NULL; - -GType -g_sheet_uniform_column_get_type (void) -{ - static GType uniform_column_type = 0; - - if (!uniform_column_type) - { - static const GTypeInfo uniform_column_info = - { - sizeof (GSheetUniformColumnClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) g_sheet_uniform_column_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GSheetUniformColumn), - 0, - (GInstanceInitFunc) g_sheet_uniform_column_init, - }; - - static const GInterfaceInfo column_info = - { - (GInterfaceInitFunc) g_sheet_column_init, - NULL, - NULL - }; - - uniform_column_type = - g_type_register_static (G_TYPE_OBJECT, "g_sheet_uniform_column", - &uniform_column_info, 0); - - g_type_add_interface_static (uniform_column_type, - G_TYPE_SHEET_COLUMN, - &column_info); - } - - return uniform_column_type; -} - - -/** - * g_sheet_uniform_column_new: - * @width: The size of columns in this uniform column - * - * Return value: a new #g_sheet_uniform_column - **/ -GObject * -g_sheet_uniform_column_new (gint width, gint n_columns) -{ - GSheetUniformColumn *ug; - GObject *retval; - - retval = g_object_new (G_TYPE_SHEET_UNIFORM_COLUMN, NULL); - - ug = G_SHEET_UNIFORM_COLUMN(retval); - ug->n_columns = n_columns; - ug->width = width; - ug->is_sensitive = FALSE; - - return retval; -} - -static gint -g_sheet_uniform_column_get_width (const GSheetColumn *geom, glong u) -{ - GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom); - - return ug->width; -} - -static gboolean -g_sheet_uniform_column_get_sensitivity (const GSheetColumn *geom, glong u) -{ - GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom); - - return ug->is_sensitive; -} - - -static gchar * -g_sheet_uniform_column_get_button_label (const GSheetColumn *geom, glong u) -{ - gchar *label = g_strdup_printf ("%ld", u); - - return label; -} - - -static GtkJustification -g_sheet_uniform_column_get_justification (const GSheetColumn *geom, glong u) -{ - return GTK_JUSTIFY_FILL; -} - - - -static glong -g_sheet_uniform_column_get_column_count (const GSheetColumn *geom) -{ - GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom); - - return ug->n_columns; -} - -static void -g_sheet_uniform_column_class_init (GSheetUniformColumnClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GObjectClass*) class; - - object_class->finalize = g_sheet_uniform_column_finalize; - -} - - -static void -g_sheet_uniform_column_init (GSheetUniformColumn *o) -{ -} - -static void -g_sheet_uniform_column_finalize (GObject *object) -{ -} - - -static void -g_sheet_column_init (GSheetColumnIface *iface) -{ - iface->get_width = g_sheet_uniform_column_get_width ; - iface->get_sensitivity = g_sheet_uniform_column_get_sensitivity ; - iface->get_justification = g_sheet_uniform_column_get_justification; - iface->get_column_count = g_sheet_uniform_column_get_column_count; - iface->get_button_label = g_sheet_uniform_column_get_button_label; -} - diff --git a/lib/gtksheet/gsheet-uniform-column.h b/lib/gtksheet/gsheet-uniform-column.h deleted file mode 100644 index 51fc53a0..00000000 --- a/lib/gtksheet/gsheet-uniform-column.h +++ /dev/null @@ -1,67 +0,0 @@ -/* GtkSheet widget for Gtk+. - * Copyright (C) 2006 Free Software Foundation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __G_SHEET_UNIFORM_COLUMN_H__ -#define __G_SHEET_UNIFORM_COLUMN_H__ - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define G_TYPE_SHEET_UNIFORM_COLUMN (g_sheet_uniform_column_get_type ()) - -#define G_SHEET_UNIFORM_COLUMN(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, G_TYPE_SHEET_UNIFORM_COLUMN, GSheetUniformColumn ) -#define G_SHEET_UNIFORM_COLUMN_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, g_sheet_uniform_column_get_type (), GSheetUniformColumnClass) -#define G_IS_SHEET_UNIFORM_COLUMN(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_SHEET_UNIFORM_COLUMN) - - - struct _GSheetUniformColumn{ - GObject parent; - - gint n_columns; - gint width; - gboolean is_sensitive; - }; - - struct _GSheetUniformColumnClass - { - GObjectClass parent_class; - }; - - /* create a new column */ - GObject * g_sheet_uniform_column_new (gint width, gint n_columns); - - GType g_sheet_uniform_column_get_type (void); - - - typedef struct _GSheetUniformColumn GSheetUniformColumn; - typedef struct _GSheetUniformColumnClass GSheetUniformColumnClass; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __G_SHEET_UNIFORM_COLUMN_H__ */ - - diff --git a/lib/gtksheet/gsheetmodel.c b/lib/gtksheet/gsheetmodel.c index f06dc638..7e975237 100644 --- a/lib/gtksheet/gsheetmodel.c +++ b/lib/gtksheet/gsheetmodel.c @@ -508,3 +508,54 @@ g_sheet_model_get_row_count(const GSheetModel *model) return G_SHEET_MODEL_GET_IFACE (model)->get_row_count (model); } + + + +/* New functions since AXIS_TRANSITION */ +gboolean +g_sheet_model_get_column_sensitivity (const GSheetModel *model, gint col) +{ + if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity) + return TRUE; + + return G_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity (model, col); +} + + +gchar * +g_sheet_model_get_column_subtitle (const GSheetModel *model, + gint col) +{ + g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL); + + if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle) + return NULL; + + return G_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle (model, col); +} + + +GtkSheetButton * +g_sheet_model_get_column_button (const GSheetModel *model, + gint col) +{ + GtkSheetButton *button = gtk_sheet_button_new (); + + g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL); + + if ( G_SHEET_MODEL_GET_IFACE (model)->get_column_title) + button->label = G_SHEET_MODEL_GET_IFACE (model)->get_column_title (model, col); + + return button; +} + +GtkJustification +g_sheet_model_get_column_justification (const GSheetModel *model, + gint col) +{ + if ( G_SHEET_MODEL_GET_IFACE (model)->get_column_justification) + return G_SHEET_MODEL_GET_IFACE (model)->get_column_justification (model, col); + + return GTK_JUSTIFY_LEFT; +} + diff --git a/lib/gtksheet/gsheetmodel.h b/lib/gtksheet/gsheetmodel.h index 43583eb3..eb661c99 100644 --- a/lib/gtksheet/gsheetmodel.h +++ b/lib/gtksheet/gsheetmodel.h @@ -26,7 +26,7 @@ #include #include #include - +#include "gtkextra-sheet.h" G_BEGIN_DECLS @@ -51,8 +51,8 @@ typedef struct _GtkSheetCellBorder GtkSheetCellBorder; struct _GtkSheetRange { - glong row0,col0; /* upper-left cell */ - glong rowi,coli; /* lower-right cell */ + glong row0, col0; /* upper-left cell */ + glong rowi, coli; /* lower-right cell */ }; struct _GtkSheetCellBorder @@ -93,6 +93,8 @@ struct _GSheetModelIface + + /* Virtual Table */ gchar * (* get_string) (const GSheetModel *sheet_model, @@ -123,10 +125,20 @@ struct _GSheetModelIface glong row, glong column); + + /* column related metadata */ + + gchar * (*get_column_title) (const GSheetModel *mode, gint col); + gchar * (*get_column_subtitle) (const GSheetModel *mode, gint col); + gboolean * (*get_column_sensitivity) (const GSheetModel *mode, gint col); + GtkJustification (*get_column_justification) (const GSheetModel *mode, gint col); + const GtkSheetButton * (* get_button) (const GSheetModel *model, gint col); + glong (*get_column_count) (const GSheetModel *model); - glong (*get_row_count) (const GSheetModel *model); + /* row related metadata */ + glong (*get_row_count) (const GSheetModel *model); }; @@ -192,6 +204,20 @@ glong g_sheet_model_get_column_count (const GSheetModel *sheet_model); gint g_sheet_model_get_row_count (const GSheetModel *sheet_model); + + +gboolean g_sheet_model_get_column_sensitivity (const GSheetModel *model, + gint col); + +gchar * g_sheet_model_get_column_subtitle (const GSheetModel *model, + gint col); + +GtkSheetButton * g_sheet_model_get_column_button (const GSheetModel *, gint); + +GtkJustification g_sheet_model_get_column_justification (const GSheetModel *, + gint); + + G_END_DECLS #endif /* __G_SHEET_MODEL_H__ */ diff --git a/lib/gtksheet/gtksheet.c b/lib/gtksheet/gtksheet.c index e38b3895..8b25902c 100644 --- a/lib/gtksheet/gtksheet.c +++ b/lib/gtksheet/gtksheet.c @@ -160,7 +160,7 @@ max_fully_visible_row (const GtkSheet *sheet) glong row = max_visible_row (sheet); if ( g_sheet_row_start_pixel (sheet->row_geometry, row) - + + + g_sheet_row_get_height (sheet->row_geometry, row) > sheet->vadjustment->value) row--; @@ -169,26 +169,11 @@ max_fully_visible_row (const GtkSheet *sheet) } -/* returns the column index from a x pixel location */ +/* returns the column index from a pixel location */ static inline gint -column_from_xpixel (const GtkSheet *sheet, gint x) +column_from_xpixel (const GtkSheet *sheet, gint pixel) { - gint i; - gint cx = 0; - - if (x < 0) return -1; - for (i = 0; - i < g_sheet_column_get_column_count (sheet->column_geometry); i++) - { - if (x >= cx && - x <= (cx + g_sheet_column_get_width (sheet->column_geometry, i))) - return i; - - cx += g_sheet_column_get_width (sheet->column_geometry, i); - } - - /* no match */ - return g_sheet_column_get_column_count (sheet->column_geometry) - 1; + return psppire_axis_get_unit_at_pixel (sheet->haxis, pixel); } @@ -205,7 +190,7 @@ min_fully_visible_column (const GtkSheet *sheet) { glong col = min_visible_column (sheet); - if ( g_sheet_column_start_pixel (sheet->column_geometry, col) < sheet->hadjustment->value) + if ( psppire_axis_pixel_start (sheet->haxis, col) < sheet->hadjustment->value) col++; return col; @@ -227,9 +212,9 @@ max_fully_visible_column (const GtkSheet *sheet) { glong col = max_visible_column (sheet); - if ( g_sheet_column_start_pixel (sheet->column_geometry, col) + if ( psppire_axis_pixel_start (sheet->haxis, col) + - g_sheet_column_get_width (sheet->column_geometry, col) + psppire_axis_unit_size (sheet->haxis, col) > sheet->hadjustment->value) col--; @@ -304,9 +289,9 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, *drag_column = column_from_xpixel (sheet, x); *drag_row = yyy_row_ypixel_to_row (sheet, y); - if (x >= g_sheet_column_start_pixel (sheet->column_geometry, sheet->range.col0) - DRAG_WIDTH / 2 && - x <= g_sheet_column_start_pixel (sheet->column_geometry, sheet->range.coli) + - g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli) + DRAG_WIDTH / 2) + if (x >= psppire_axis_pixel_start (sheet->haxis, sheet->range.col0) - DRAG_WIDTH / 2 && + x <= psppire_axis_pixel_start (sheet->haxis, sheet->range.coli) + + psppire_axis_unit_size (sheet->haxis, sheet->range.coli) + DRAG_WIDTH / 2) { ydrag = g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.row0); if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) @@ -327,14 +312,14 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, y <= g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.rowi) + g_sheet_row_get_height (sheet->row_geometry, sheet->range.rowi) + DRAG_WIDTH / 2) { - xdrag = g_sheet_column_start_pixel (sheet->column_geometry, sheet->range.col0); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.col0); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) { *drag_column = sheet->range.col0; return TRUE; } - xdrag = g_sheet_column_start_pixel (sheet->column_geometry, sheet->range.coli) + - g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.coli) + + psppire_axis_unit_size (sheet->haxis, sheet->range.coli); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) { *drag_column = sheet->range.coli; @@ -356,8 +341,8 @@ POSSIBLE_RESIZE (const GtkSheet *sheet, gint x, gint y, sheet->range.col0 < 0 || sheet->range.coli < 0 ) return FALSE; - xdrag = g_sheet_column_start_pixel (sheet->column_geometry, sheet->range.coli)+ - g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.coli)+ + psppire_axis_unit_size (sheet->haxis, sheet->range.coli); ydrag = g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.rowi) + g_sheet_row_get_height (sheet->row_geometry, sheet->range.rowi); @@ -366,7 +351,7 @@ POSSIBLE_RESIZE (const GtkSheet *sheet, gint x, gint y, ydrag = g_sheet_row_start_pixel (sheet->row_geometry, min_visible_row (sheet)); if (sheet->state == GTK_SHEET_ROW_SELECTED) - xdrag = g_sheet_column_start_pixel (sheet->column_geometry, min_visible_column (sheet)); + xdrag = psppire_axis_pixel_start (sheet->haxis, min_visible_column (sheet)); *drag_column = column_from_xpixel (sheet, x); *drag_row = yyy_row_ypixel_to_row (sheet, y); @@ -384,7 +369,7 @@ rectangle_from_range (GtkSheet *sheet, const GtkSheetRange *range, { g_return_val_if_fail (range, FALSE); - r->x = g_sheet_column_start_pixel (sheet->column_geometry, range->col0); + r->x = psppire_axis_pixel_start (sheet->haxis, range->col0); r->x -= round (sheet->hadjustment->value); if ( sheet->row_titles_visible) @@ -397,9 +382,9 @@ rectangle_from_range (GtkSheet *sheet, const GtkSheetRange *range, if ( sheet->column_titles_visible) r->y += sheet->column_title_area.height; - r->width = g_sheet_column_start_pixel (sheet->column_geometry, range->coli) - - g_sheet_column_start_pixel (sheet->column_geometry, range->col0) + - g_sheet_column_get_width (sheet->column_geometry, range->coli); + r->width = psppire_axis_pixel_start (sheet->haxis, range->coli) - + psppire_axis_pixel_start (sheet->haxis, range->col0) + + psppire_axis_unit_size (sheet->haxis, range->coli); r->height = g_sheet_row_start_pixel (sheet->row_geometry, range->rowi) - g_sheet_row_start_pixel (sheet->row_geometry, range->row0) + @@ -695,7 +680,7 @@ enum { PROP_0, PROP_ROW_GEO, - PROP_COL_GEO, + PROP_HAXIS, PROP_MODEL }; @@ -710,13 +695,15 @@ gtk_sheet_set_row_geometry (GtkSheet *sheet, GSheetRow *geo) } static void -gtk_sheet_set_column_geometry (GtkSheet *sheet, GSheetColumn *geo) +gtk_sheet_set_horizontal_axis (GtkSheet *sheet, PsppireAxis *a) { - if ( sheet->column_geometry ) g_object_unref (sheet->column_geometry); + if ( sheet->haxis ) + g_object_unref (sheet->haxis); - sheet->column_geometry = geo; + sheet->haxis = a; - if ( sheet->column_geometry ) g_object_ref (sheet->column_geometry); + if ( sheet->haxis ) + g_object_ref (sheet->haxis); } @@ -734,8 +721,8 @@ gtk_sheet_set_property (GObject *object, case PROP_ROW_GEO: gtk_sheet_set_row_geometry (sheet, g_value_get_pointer (value)); break; - case PROP_COL_GEO: - gtk_sheet_set_column_geometry (sheet, g_value_get_pointer (value)); + case PROP_HAXIS: + gtk_sheet_set_horizontal_axis (sheet, g_value_get_pointer (value)); break; case PROP_MODEL: gtk_sheet_set_model (sheet, g_value_get_pointer (value)); @@ -759,8 +746,8 @@ gtk_sheet_get_property (GObject *object, case PROP_ROW_GEO: g_value_set_pointer (value, sheet->row_geometry); break; - case PROP_COL_GEO: - g_value_set_pointer (value, sheet->column_geometry); + case PROP_HAXIS: + g_value_set_pointer (value, sheet->haxis); break; case PROP_MODEL: g_value_set_pointer (value, sheet->model); @@ -778,7 +765,7 @@ gtk_sheet_class_init (GtkSheetClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GParamSpec *row_geo_spec ; - GParamSpec *col_geo_spec ; + GParamSpec *haxis_spec ; GParamSpec *model_spec ; GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); @@ -987,10 +974,10 @@ gtk_sheet_class_init (GtkSheetClass *klass) "A pointer to the model of the row geometry", G_PARAM_READABLE | G_PARAM_WRITABLE ); - col_geo_spec = - g_param_spec_pointer ("column-geometry", - "Column Geometry", - "A pointer to the model of the column geometry", + haxis_spec = + g_param_spec_pointer ("horizontal-axis", + "Horizontal Axis", + "A pointer to the PsppireAxis object for the columns", G_PARAM_READABLE | G_PARAM_WRITABLE ); model_spec = @@ -1008,8 +995,8 @@ gtk_sheet_class_init (GtkSheetClass *klass) row_geo_spec); g_object_class_install_property (object_class, - PROP_COL_GEO, - col_geo_spec); + PROP_HAXIS, + haxis_spec); g_object_class_install_property (object_class, PROP_MODEL, @@ -1048,7 +1035,7 @@ static void gtk_sheet_init (GtkSheet *sheet) { sheet->model = NULL; - sheet->column_geometry = NULL; + sheet->haxis = NULL; sheet->row_geometry = NULL; sheet->flags = 0; @@ -1138,7 +1125,7 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column, */ range.col0 = first_column; range.row0 = 0; - range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + range.coli = psppire_axis_unit_count (sheet->haxis) - 1; range.rowi = g_sheet_row_get_row_count (sheet->row_geometry) - 1; adjust_scrollbars (sheet); @@ -1170,7 +1157,7 @@ rows_inserted_deleted_callback (GSheetModel *model, gint first_row, range.row0 = first_row; range.col0 = 0; range.rowi = g_sheet_row_get_row_count (sheet->row_geometry) - 1; - range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + range.coli = psppire_axis_unit_count (sheet->haxis) - 1; adjust_scrollbars (sheet); @@ -1249,11 +1236,10 @@ range_update_callback (GSheetModel *m, gint row0, gint col0, * Returns: the new sheet widget */ GtkWidget * -gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo, GSheetModel *model) +gtk_sheet_new (GSheetRow *vgeo, void *hgeo, GSheetModel *model) { GtkWidget *widget = g_object_new (GTK_TYPE_SHEET, "row-geometry", vgeo, - "column-geometry", hgeo, "model", model, NULL); return widget; @@ -1351,7 +1337,7 @@ gtk_sheet_get_columns_count (GtkSheet *sheet) g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - return g_sheet_column_get_column_count (sheet->column_geometry); + return psppire_axis_unit_count (sheet->haxis); } static void @@ -1481,7 +1467,7 @@ gtk_sheet_moveto (GtkSheet *sheet, g_return_if_fail (col_align <= 1); g_return_if_fail (col < - g_sheet_column_get_column_count (sheet->column_geometry)); + psppire_axis_unit_count (sheet->haxis)); g_return_if_fail (row < g_sheet_row_get_row_count (sheet->row_geometry)); @@ -1498,7 +1484,7 @@ gtk_sheet_moveto (GtkSheet *sheet, if (col >= 0) { - gint x = g_sheet_column_start_pixel (sheet->column_geometry, col); + gint x = psppire_axis_pixel_start (sheet->haxis, col); gtk_adjustment_set_value (sheet->hadjustment, x - width * col_align); } @@ -1541,7 +1527,7 @@ gtk_sheet_select_row (GtkSheet *sheet, gint row) sheet->range.row0 = row; sheet->range.col0 = 0; sheet->range.rowi = row; - sheet->range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + sheet->range.coli = psppire_axis_unit_count (sheet->haxis) - 1; sheet->active_cell.row = row; sheet->active_cell.col = 0; @@ -1556,7 +1542,7 @@ gtk_sheet_select_column (GtkSheet *sheet, gint column) g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column < 0 || column >= g_sheet_column_get_column_count (sheet->column_geometry)) + if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis)) return; if (sheet->state != GTK_SHEET_NORMAL) @@ -1589,10 +1575,10 @@ gtk_sheet_range_isvisible (const GtkSheet *sheet, if (range.rowi < 0 || range.rowi >= g_sheet_row_get_row_count (sheet->row_geometry)) return FALSE; - if (range.col0 < 0 || range.col0 >= g_sheet_column_get_column_count (sheet->column_geometry)) + if (range.col0 < 0 || range.col0 >= psppire_axis_unit_count (sheet->haxis)) return FALSE; - if (range.coli < 0 || range.coli >= g_sheet_column_get_column_count (sheet->column_geometry)) + if (range.coli < 0 || range.coli >= psppire_axis_unit_count (sheet->haxis)) return FALSE; if (range.rowi < min_visible_row (sheet)) @@ -1697,7 +1683,7 @@ gtk_sheet_dispose (GObject *object) if (sheet->model) g_object_unref (sheet->model); if (sheet->row_geometry) g_object_unref (sheet->row_geometry); - if (sheet->column_geometry) g_object_unref (sheet->column_geometry); + if (sheet->haxis) g_object_unref (sheet->haxis); g_object_unref (sheet->entry_container); sheet->entry_container = NULL; @@ -2071,7 +2057,7 @@ gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint col) return; if (col < 0 || - col >= g_sheet_column_get_column_count (sheet->column_geometry)) + col >= psppire_axis_unit_count (sheet->haxis)) return; gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -2271,16 +2257,11 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) gtk_sheet_draw_border (sheet, sheet->range); } -static void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, - GtkJustification justification, - const gchar *text); - - static inline gint safe_strcmp (const gchar *s1, const gchar *s2) { if ( !s1 && !s2) return 0; - if ( !s1) return - 1; + if ( !s1) return -1; if ( !s2) return +1; return strcmp (s1, s2); } @@ -2296,7 +2277,7 @@ gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (col >= g_sheet_column_get_column_count (sheet->column_geometry) + if (col >= psppire_axis_unit_count (sheet->haxis) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; @@ -2306,6 +2287,9 @@ gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, old_text = g_sheet_model_get_string (model, row, col); + if (0 != safe_strcmp (old_text, text)) + g_sheet_model_set_string (model, text, row, col); + if ( g_sheet_model_free_strings (model)) g_free (old_text); } @@ -2318,7 +2302,7 @@ gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint column) g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column >= g_sheet_column_get_column_count (sheet->column_geometry) || + if (column >= psppire_axis_unit_count (sheet->haxis) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; if (column < 0 || row < 0) return; @@ -2355,7 +2339,7 @@ gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col) g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - if (col >= g_sheet_column_get_column_count (sheet->column_geometry) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) + if (col >= psppire_axis_unit_count (sheet->haxis) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return NULL; if (col < 0 || row < 0) return NULL; @@ -2376,7 +2360,7 @@ gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - if (col >= g_sheet_column_get_column_count (sheet->column_geometry) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return 0; + if (col >= psppire_axis_unit_count (sheet->haxis) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return 0; if (col < 0 || row < 0) return 0; state = sheet->state; @@ -2459,7 +2443,7 @@ gtk_sheet_get_pixel_info (GtkSheet *sheet, else { tcol = column_from_xpixel (sheet, x); - if (tcol > g_sheet_column_get_column_count (sheet->column_geometry)) + if (tcol > psppire_axis_unit_count (sheet->haxis)) return FALSE; } @@ -2477,14 +2461,14 @@ gtk_sheet_get_cell_area (GtkSheet *sheet, g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - if (row >= g_sheet_row_get_row_count (sheet->row_geometry) || column >= g_sheet_column_get_column_count (sheet->column_geometry)) + if (row >= g_sheet_row_get_row_count (sheet->row_geometry) || column >= psppire_axis_unit_count (sheet->haxis)) return FALSE; - area->x = (column == -1) ? 0 : g_sheet_column_start_pixel (sheet->column_geometry, column); + area->x = (column == -1) ? 0 : psppire_axis_pixel_start (sheet->haxis, column); area->y = (row == -1) ? 0 : g_sheet_row_start_pixel (sheet->row_geometry, row); area->width= (column == -1) ? sheet->row_title_area.width - : g_sheet_column_get_width (sheet->column_geometry, column); + : psppire_axis_unit_size (sheet->haxis, column); area->height= (row == -1) ? sheet->column_title_area.height : g_sheet_row_get_height (sheet->row_geometry, row); @@ -2503,7 +2487,7 @@ gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint col) if (row >= g_sheet_row_get_row_count (sheet->row_geometry) || - col >= g_sheet_column_get_column_count (sheet->column_geometry)) + col >= psppire_axis_unit_count (sheet->haxis)) return; sheet->active_cell.row = row; @@ -2558,6 +2542,8 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data) text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); + + if (text && strlen (text) > 0) { gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -2612,7 +2598,7 @@ change_active_cell (GtkSheet *sheet, gint row, gint col) return; if ( row > g_sheet_row_get_row_count (sheet->row_geometry) - || col > g_sheet_column_get_column_count (sheet->column_geometry)) + || col > psppire_axis_unit_count (sheet->haxis)) return; if (sheet->state != GTK_SHEET_NORMAL) @@ -2795,10 +2781,10 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (mask1 != mask2) { - x = g_sheet_column_start_pixel (sheet->column_geometry, j); + x = psppire_axis_pixel_start (sheet->haxis, j); y = g_sheet_row_start_pixel (sheet->row_geometry, i); - width = g_sheet_column_start_pixel (sheet->column_geometry, j)- x+ - g_sheet_column_get_width (sheet->column_geometry, j); + width = psppire_axis_pixel_start (sheet->haxis, j)- x+ + psppire_axis_unit_size (sheet->haxis, j); height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == sheet->range.row0) @@ -2816,10 +2802,10 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (i != sheet->active_cell.row || j != sheet->active_cell.col) { - x = g_sheet_column_start_pixel (sheet->column_geometry, j); + x = psppire_axis_pixel_start (sheet->haxis, j); y = g_sheet_row_start_pixel (sheet->row_geometry, i); - width = g_sheet_column_start_pixel (sheet->column_geometry, j)- x+ - g_sheet_column_get_width (sheet->column_geometry, j); + width = psppire_axis_pixel_start (sheet->haxis, j)- x+ + psppire_axis_unit_size (sheet->haxis, j); height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); @@ -2859,9 +2845,9 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (state == GTK_STATE_SELECTED && !selected) { - x = g_sheet_column_start_pixel (sheet->column_geometry, j); + x = psppire_axis_pixel_start (sheet->haxis, j); y = g_sheet_row_start_pixel (sheet->row_geometry, i); - width = g_sheet_column_start_pixel (sheet->column_geometry, j) - x + g_sheet_column_get_width (sheet->column_geometry, j); + width = psppire_axis_pixel_start (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j); height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == sheet->range.row0) @@ -2894,9 +2880,9 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) (i != sheet->active_cell.row || j != sheet->active_cell.col)) { - x = g_sheet_column_start_pixel (sheet->column_geometry, j); + x = psppire_axis_pixel_start (sheet->haxis, j); y = g_sheet_row_start_pixel (sheet->row_geometry, i); - width = g_sheet_column_start_pixel (sheet->column_geometry, j) - x + g_sheet_column_get_width (sheet->column_geometry, j); + width = psppire_axis_pixel_start (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j); height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == new_range.row0) @@ -2940,9 +2926,9 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) mask2 = j == new_range.coli ? mask2 + 8 : mask2; if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED)) { - x = g_sheet_column_start_pixel (sheet->column_geometry, j); + x = psppire_axis_pixel_start (sheet->haxis, j); y = g_sheet_row_start_pixel (sheet->row_geometry, i); - width = g_sheet_column_get_width (sheet->column_geometry, j); + width = psppire_axis_unit_size (sheet->haxis, j); height = g_sheet_row_get_height (sheet->row_geometry, i); if (mask2 & 1) gdk_draw_rectangle (sheet->sheet_window, @@ -3232,7 +3218,7 @@ gtk_sheet_button_press (GtkWidget *widget, sheet_signals[BUTTON_EVENT_COLUMN], 0, column, event); - if (g_sheet_column_get_sensitivity (sheet->column_geometry, column)) + if (g_sheet_model_get_column_sensitivity (sheet->model, column)) { if ( event->type == GDK_2BUTTON_PRESS && event->button == 1) g_signal_emit (sheet, @@ -3399,7 +3385,7 @@ gtk_sheet_button_press (GtkWidget *widget, column = column_from_xpixel (sheet, x); - if (g_sheet_column_get_sensitivity (sheet->column_geometry, column)) + if (g_sheet_model_get_column_sensitivity (sheet->model, column)) { veto = gtk_sheet_click_cell (sheet, -1, column); gtk_grab_add (GTK_WIDGET (sheet)); @@ -3439,7 +3425,7 @@ gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column) cell.col = column; if (row >= g_sheet_row_get_row_count (sheet->row_geometry) - || column >= g_sheet_column_get_column_count (sheet->column_geometry)) + || column >= psppire_axis_unit_count (sheet->haxis)) { return FALSE; } @@ -3479,7 +3465,7 @@ gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column) sheet->range.col0 = 0; sheet->range.rowi = g_sheet_row_get_row_count (sheet->row_geometry) - 1; sheet->range.coli = - g_sheet_column_get_column_count (sheet->column_geometry) - 1; + psppire_axis_unit_count (sheet->haxis) - 1; sheet->active_cell.row = 0; sheet->active_cell.col = 0; gtk_sheet_select_range (sheet, NULL); @@ -3750,9 +3736,7 @@ motion_timeout_callback (gpointer data) if (sheet->row_title_under) { GSheetRow *row_geo = sheet->row_geometry; - gchar *text; - - text = g_sheet_row_get_subtitle (row_geo, row); + gchar *text = g_sheet_row_get_subtitle (row_geo, row); show_subtitle (sheet, row, -1, text); g_free (text); @@ -3760,10 +3744,8 @@ motion_timeout_callback (gpointer data) if (sheet->column_title_under) { - GSheetColumn *col_geo = sheet->column_geometry; - gchar *text; - - text = g_sheet_column_get_subtitle (col_geo, column); + gchar *text = g_sheet_model_get_column_subtitle (sheet->model, + column); show_subtitle (sheet, -1, column, text); @@ -3961,7 +3943,7 @@ gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event) sheet->y_drag = y; aux = sheet->range; if (aux.row0 + row >= 0 && aux.rowi + row < g_sheet_row_get_row_count (sheet->row_geometry) && - aux.col0 + column >= 0 && aux.coli + column < g_sheet_column_get_column_count (sheet->column_geometry)) + aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis)) { aux = sheet->drag_range; sheet->drag_range.row0 = sheet->range.row0 + row; @@ -3983,7 +3965,7 @@ gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event) GtkSheetRange aux; gint v_h, current_col, current_row, col_threshold, row_threshold; v_h = 1; - if (abs (x - g_sheet_column_start_pixel (sheet->column_geometry, sheet->drag_cell.col)) > + if (abs (x - psppire_axis_pixel_start (sheet->haxis, sheet->drag_cell.col)) > abs (y - g_sheet_row_start_pixel (sheet->row_geometry, sheet->drag_cell.row))) v_h = 2; current_col = column_from_xpixel (sheet, x); @@ -3993,8 +3975,8 @@ gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event) /*use half of column width resp. row height as threshold to expand selection*/ - col_threshold = g_sheet_column_start_pixel (sheet->column_geometry, current_col) + - g_sheet_column_get_width (sheet->column_geometry, current_col) / 2; + col_threshold = psppire_axis_pixel_start (sheet->haxis, current_col) + + psppire_axis_unit_size (sheet->haxis, current_col) / 2; if (column > 0) { if (x < col_threshold) @@ -4030,7 +4012,7 @@ gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event) row = 0; if (aux.row0 + row >= 0 && aux.rowi + row < g_sheet_row_get_row_count (sheet->row_geometry) && - aux.col0 + column >= 0 && aux.coli + column < g_sheet_column_get_column_count (sheet->column_geometry)) + aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis)) { aux = sheet->drag_range; sheet->drag_range = sheet->range; @@ -4098,7 +4080,7 @@ gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column) switch (sheet->state) { case GTK_SHEET_ROW_SELECTED: - column = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + column = psppire_axis_unit_count (sheet->haxis) - 1; break; case GTK_SHEET_COLUMN_SELECTED: row = g_sheet_row_get_row_count (sheet->row_geometry) - 1; @@ -4223,7 +4205,7 @@ step_sheet (GtkSheet *sheet, GtkScrollType dir) g_sheet_row_get_row_count (sheet->row_geometry) - 1); minimize_int (&new_cell.col, - g_sheet_column_get_column_count (sheet->column_geometry) - 1); + psppire_axis_unit_count (sheet->haxis) - 1); g_signal_emit (sheet, sheet_signals[TRAVERSE], 0, &sheet->active_cell, @@ -4238,7 +4220,7 @@ step_sheet (GtkSheet *sheet, GtkScrollType dir) if ( new_cell.col > max_fully_visible_column (sheet)) { glong hpos = - g_sheet_column_start_pixel (sheet->column_geometry, + psppire_axis_pixel_start (sheet->haxis, new_cell.col + 1); hpos -= sheet->hadjustment->page_size; @@ -4248,7 +4230,7 @@ step_sheet (GtkSheet *sheet, GtkScrollType dir) else if ( new_cell.col < min_fully_visible_column (sheet)) { glong hpos = - g_sheet_column_start_pixel (sheet->column_geometry, + psppire_axis_pixel_start (sheet->haxis, new_cell.col); gtk_adjustment_set_value (sheet->hadjustment, @@ -4483,7 +4465,7 @@ draw_column_title_buttons (GtkSheet *sheet) } if (max_visible_column (sheet) == - g_sheet_column_get_column_count (sheet->column_geometry) - 1) + psppire_axis_unit_count (sheet->haxis) - 1) gdk_window_clear_area (sheet->column_title_window, 0, 0, sheet->column_title_area.width, @@ -4826,18 +4808,15 @@ draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint last) gboolean is_sensitive = FALSE; GtkSheetButton * - button = g_sheet_column_get_button (sheet->column_geometry, col); + button = g_sheet_model_get_column_button (sheet->model, col); allocation.y = 0; - allocation.x = - g_sheet_column_start_pixel (sheet->column_geometry, col) + allocation.x = psppire_axis_pixel_start (sheet->haxis, col) + CELL_SPACING; allocation.x -= sheet->hadjustment->value; allocation.height = sheet->column_title_area.height; - allocation.width = - g_sheet_column_get_width (sheet->column_geometry, col); - is_sensitive = - g_sheet_column_get_sensitivity (sheet->column_geometry, col); + allocation.width = psppire_axis_unit_size (sheet->haxis, col); + is_sensitive = g_sheet_model_get_column_sensitivity (sheet->model, col); draw_button (sheet, sheet->column_title_window, button, is_sensitive, allocation); @@ -4947,12 +4926,12 @@ adjust_scrollbars (GtkSheet *sheet) sheet->hadjustment->page_increment = width; - last_col = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + last_col = psppire_axis_unit_count (sheet->haxis) - 1; sheet->hadjustment->upper = - g_sheet_column_start_pixel (sheet->column_geometry, last_col) + psppire_axis_pixel_start (sheet->haxis, last_col) + - g_sheet_column_get_width (sheet->column_geometry, last_col) + psppire_axis_unit_size (sheet->haxis, last_col) ; sheet->hadjustment->lower = 0; @@ -5067,10 +5046,10 @@ draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) GdkRectangle clip_area, area; GdkGCValues values; - area.x = g_sheet_column_start_pixel (sheet->column_geometry, range.col0); + area.x = psppire_axis_pixel_start (sheet->haxis, range.col0); area.y = g_sheet_row_start_pixel (sheet->row_geometry, range.row0); - area.width = g_sheet_column_start_pixel (sheet->column_geometry, range.coli)- area.x+ - g_sheet_column_get_width (sheet->column_geometry, range.coli); + area.width = psppire_axis_pixel_start (sheet->haxis, range.coli)- area.x+ + psppire_axis_unit_size (sheet->haxis, range.coli); area.height = g_sheet_row_start_pixel (sheet->row_geometry, range.rowi)- area.y + g_sheet_row_get_height (sheet->row_geometry, range.rowi); @@ -5125,7 +5104,7 @@ draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) static guint new_column_width (GtkSheet *sheet, gint column, gint *x) { - gint left_pos = g_sheet_column_start_pixel (sheet->column_geometry, column) + gint left_pos = psppire_axis_pixel_start (sheet->haxis, column) - sheet->hadjustment->value; gint width = *x - left_pos; @@ -5136,7 +5115,9 @@ new_column_width (GtkSheet *sheet, gint column, gint *x) *x = left_pos + width; } +#if AXIS_TRANSITION g_sheet_column_set_width (sheet->column_geometry, column, width); +#endif draw_column_title_buttons (sheet); @@ -5184,13 +5165,15 @@ gtk_sheet_set_column_width (GtkSheet *sheet, g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column < 0 || column >= g_sheet_column_get_column_count (sheet->column_geometry)) + if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis)) return; gtk_sheet_column_size_request (sheet, column, &min_width); if (width < min_width) return; +#if AXIS_TRANSITION g_sheet_column_set_width (sheet->column_geometry, column, width); +#endif if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) { @@ -5277,7 +5260,7 @@ gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col, } attr->justification = - g_sheet_column_get_justification (sheet->column_geometry, col); + g_sheet_model_get_column_justification (sheet->model, col); j = g_sheet_model_get_justification (sheet->model, row, col); if (j) @@ -5337,7 +5320,7 @@ gtk_sheet_column_size_request (GtkSheet *sheet, { GtkRequisition button_requisition; - GtkSheetButton *button = g_sheet_column_get_button (sheet->column_geometry, col); + GtkSheetButton *button = g_sheet_model_get_column_button (sheet->model, col); gtk_sheet_button_size_request (sheet, button, @@ -5401,7 +5384,6 @@ gtk_sheet_button_free (GtkSheetButton *button) g_free (button); } - static void append_cell_text (GString *string, const GtkSheet *sheet, gint r, gint c) { diff --git a/lib/gtksheet/gtksheet.h b/lib/gtksheet/gtksheet.h index fa1ac422..de308a60 100644 --- a/lib/gtksheet/gtksheet.h +++ b/lib/gtksheet/gtksheet.h @@ -30,9 +30,8 @@ #include "gtkextra-sheet.h" #include "gsheetmodel.h" -#include "gsheet-column-iface.h" #include "gsheet-row-iface.h" - +#include "psppire-axis.h" G_BEGIN_DECLS @@ -91,7 +90,10 @@ struct _GtkSheet GtkBin parent; gboolean dispose_has_run; + /* GSheetColumn *column_geometry; + */ + PsppireAxis *haxis; GSheetRow *row_geometry; guint16 flags; @@ -231,18 +233,18 @@ GtkType gtk_sheet_range_get_type (void); /* create a new sheet */ -GtkWidget * gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo, +GtkWidget * gtk_sheet_new (GSheetRow *vgeo, void *hgeo, GSheetModel *model); /* create a new sheet with custom entry */ GtkWidget * gtk_sheet_new_with_custom_entry (GSheetRow *vgeo, - GSheetColumn *hgeo, + void *hgeo, GtkType entry_type); void gtk_sheet_construct_with_custom_entry (GtkSheet *sheet, GSheetRow *vgeo, - GSheetColumn *hgeo, + void *hgeo, GtkType entry_type); /* Change entry */ void gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type); diff --git a/lib/gtksheet/psppire-axis.c b/lib/gtksheet/psppire-axis.c new file mode 100644 index 00000000..a3609afa --- /dev/null +++ b/lib/gtksheet/psppire-axis.c @@ -0,0 +1,204 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 Free Software Foundation + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include +#include + +#include +#include +#include "psppire-axis.h" +#include + + +/* --- prototypes --- */ +static void psppire_axis_class_init (PsppireAxisClass *class); +static void psppire_axis_init (PsppireAxis *axis); +static void psppire_axis_finalize (GObject *object); + + +/* --- variables --- */ +static GObjectClass *parent_class = NULL; + +/* --- functions --- */ +/** + * psppire_axis_get_type: + * @returns: the type ID for accelerator groups. + */ +GType +psppire_axis_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = { + sizeof (PsppireAxisClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) psppire_axis_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PsppireAxis), + 0, /* n_preallocs */ + (GInstanceInitFunc) psppire_axis_init, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "PsppireAxis", + &object_info, 0); + } + + return object_type; +} + + +static void +psppire_axis_class_init (PsppireAxisClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + object_class->finalize = psppire_axis_finalize; +} + +static void +psppire_axis_init (PsppireAxis *axis) +{ + axis->pool = NULL; + psppire_axis_clear (axis); +} + + +static void +psppire_axis_finalize (GObject *object) +{ + PsppireAxis *a = PSPPIRE_AXIS (object); + pool_destroy (a->pool); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +/** + * psppire_axis_new: + * @returns: a new #PsppireAxis object + * + * Creates a new #PsppireAxis. + */ +PsppireAxis* +psppire_axis_new (void) +{ + return g_object_new (G_TYPE_PSPPIRE_AXIS, NULL); +} + + +gint +psppire_axis_unit_size (PsppireAxis *a, gint unit) +{ + const struct tower_node *node; + if (unit >= tower_count (&a->tower)) + return 0; + + node = tower_get (&a->tower, unit); + + return tower_node_get_size (node); +} + +gint +psppire_axis_unit_count (PsppireAxis *a) +{ + return tower_count (&a->tower); +} + +glong +psppire_axis_pixel_start (PsppireAxis *a, gint unit) +{ + const struct tower_node *node; + + if ( unit >= tower_count (&a->tower)) + return tower_height (&a->tower); + + node = tower_get (&a->tower, unit); + + return tower_node_get_level (node); +} + +gint +psppire_axis_get_unit_at_pixel (PsppireAxis *a, glong pixel) +{ + const struct tower_node *node; + unsigned long int node_start; + + if (pixel >= tower_height (&a->tower)) + return tower_count (&a->tower); + + node = tower_lookup (&a->tower, pixel, &node_start); + + return tower_node_get_index (node); +} + +void +psppire_axis_append (PsppireAxis *a, gint size) +{ + struct tower_node *new = pool_malloc (a->pool, sizeof *new); + + tower_insert (&a->tower, size, new, NULL); +} + + + +/* Insert a new unit of size SIZE before position POSN */ +void +psppire_axis_insert (PsppireAxis *a, gint size, gint posn) +{ + struct tower_node *new = pool_malloc (a->pool, sizeof *new); + + struct tower_node *before = tower_get (&a->tower, posn); + + tower_insert (&a->tower, size, new, before); +} + + +void +psppire_axis_remove (PsppireAxis *a, gint posn) +{ + struct tower_node *node = tower_get (&a->tower, posn); + + tower_delete (&a->tower, node); + + pool_free (a->pool, node); +} + + +void +psppire_axis_resize_unit (PsppireAxis *a, gint size, gint posn) +{ + struct tower_node *node = tower_get (&a->tower, posn); + + tower_resize (&a->tower, node, size); +} + + + +void +psppire_axis_clear (PsppireAxis *a) +{ + pool_destroy (a->pool); + a->pool = pool_create (); + tower_init (&a->tower); +} + + diff --git a/lib/gtksheet/psppire-axis.h b/lib/gtksheet/psppire-axis.h new file mode 100644 index 00000000..72484773 --- /dev/null +++ b/lib/gtksheet/psppire-axis.h @@ -0,0 +1,92 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2008 Free Software Foundation + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + +#ifndef PSPPIRE_AXIS_H__ +#define PSPPIRE_AXIS_H__ + + +#include +#include + +#include + +G_BEGIN_DECLS + + +/* --- type macros --- */ +#define G_TYPE_PSPPIRE_AXIS (psppire_axis_get_type ()) +#define PSPPIRE_AXIS(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS, PsppireAxis)) +#define PSPPIRE_AXIS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass)) +#define PSPPIRE_IS_AXIS(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS)) +#define PSPPIRE_IS_AXIS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS)) +#define PSPPIRE_AXIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass)) + + + +/* --- typedefs & structures --- */ +typedef struct _PsppireAxis PsppireAxis; +typedef struct _PsppireAxisClass PsppireAxisClass; + +struct pool; + +struct _PsppireAxis +{ + GObject parent; + + struct tower tower; + struct pool *pool; +}; + +struct _PsppireAxisClass +{ + GObjectClass parent_class; + +}; + +GType psppire_axis_get_type (void); + +PsppireAxis* psppire_axis_new (void); + + +/* Interface between sheet and axis */ + +gint psppire_axis_unit_size (PsppireAxis *a, gint unit); + +gint psppire_axis_unit_count (PsppireAxis *a); + +glong psppire_axis_pixel_start (PsppireAxis *a, gint unit); + +gint psppire_axis_get_unit_at_pixel (PsppireAxis *a, glong pixel); + + + +/* Interface between axis and model */ + +void psppire_axis_clear (PsppireAxis *a); + +void psppire_axis_append (PsppireAxis *a, gint size); + +void psppire_axis_insert (PsppireAxis *a, gint size, gint posn); + +void psppire_axis_remove (PsppireAxis *a, gint posn); + +void psppire_axis_resize_unit (PsppireAxis *a, gint size, gint posn); + + +G_END_DECLS + +#endif /* PSPPIRE_AXIS_H__ */ diff --git a/src/data/datasheet.c b/src/data/datasheet.c index a11a1e59..fd07ed30 100644 --- a/src/data/datasheet.c +++ b/src/data/datasheet.c @@ -693,7 +693,7 @@ axis_clone (const struct axis *old) for (node = tower_first (&old->log_to_phy); node != NULL; node = tower_next (&old->log_to_phy, node)) { - unsigned long int size = tower_node_get_height (node); + unsigned long int size = tower_node_get_size (node); struct axis_group *group = tower_data (node, struct axis_group, logical); tower_insert (&new->log_to_phy, size, make_axis_group (group->phy_start), NULL); @@ -717,7 +717,7 @@ axis_hash (const struct axis *axis, struct md4_ctx *ctx) { struct axis_group *group = tower_data (tn, struct axis_group, logical); unsigned long int phy_start = group->phy_start; - unsigned long int size = tower_node_get_height (tn); + unsigned long int size = tower_node_get_size (tn); md4_process_bytes (&phy_start, sizeof phy_start, ctx); md4_process_bytes (&size, sizeof size, ctx); @@ -921,7 +921,7 @@ split_axis (struct axis *axis, unsigned long int where) if (where > group_start) { unsigned long int size_1 = where - group_start; - unsigned long int size_2 = tower_node_get_height (group_node) - size_1; + unsigned long int size_2 = tower_node_get_size (group_node) - size_1; struct tower_node *next = tower_next (&axis->log_to_phy, group_node); struct tower_node *new = make_axis_group (group->phy_start + size_1); tower_resize (&axis->log_to_phy, group_node, size_1); @@ -961,11 +961,11 @@ merge_axis_nodes (struct axis *axis, struct tower_node *node, if (next != NULL) { struct axis_group *next_group = axis_group_from_tower_node (next); - unsigned long this_height = tower_node_get_height (node); + unsigned long this_height = tower_node_get_size (node); if (group->phy_start + this_height == next_group->phy_start) { - unsigned long next_height = tower_node_get_height (next); + unsigned long next_height = tower_node_get_size (next); tower_resize (t, node, this_height + next_height); if (other_node != NULL && *other_node == next) *other_node = tower_next (t, *other_node); @@ -979,11 +979,11 @@ merge_axis_nodes (struct axis *axis, struct tower_node *node, if (prev != NULL) { struct axis_group *prev_group = axis_group_from_tower_node (prev); - unsigned long prev_height = tower_node_get_height (prev); + unsigned long prev_height = tower_node_get_size (prev); if (prev_group->phy_start + prev_height == group->phy_start) { - unsigned long this_height = tower_node_get_height (node); + unsigned long this_height = tower_node_get_size (node); group->phy_start = prev_group->phy_start; tower_resize (t, node, this_height + prev_height); if (other_node != NULL && *other_node == prev) @@ -1007,7 +1007,7 @@ check_axis_merged (const struct axis *axis UNUSED) if (prev != NULL) { struct axis_group *prev_group = axis_group_from_tower_node (prev); - unsigned long prev_height = tower_node_get_height (prev); + unsigned long prev_height = tower_node_get_size (prev); struct axis_group *node_group = axis_group_from_tower_node (node); assert (prev_group->phy_start + prev_height != node_group->phy_start); } diff --git a/src/data/dictionary.c b/src/data/dictionary.c index caf8e2fc..02c6aa76 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -1352,3 +1352,21 @@ dict_var_resized (const struct variable *v, int delta) d->callbacks->var_resized (d, var_get_dict_index (v), delta, d->cb_data); } } + +/* Called from variable.c to notify the dictionary that the variable's display width + has changed */ +void +dict_var_display_width_changed (const struct variable *v) +{ + if ( var_has_vardict (v)) + { + const struct vardict_info *vdi = var_get_vardict (v); + struct dictionary *d; + + d = vdi->dict; + + if ( d->callbacks && d->callbacks->var_display_width_changed ) + d->callbacks->var_display_width_changed (d, var_get_dict_index (v), d->cb_data); + } +} + diff --git a/src/data/dictionary.h b/src/data/dictionary.h index bb14f52e..682409e2 100644 --- a/src/data/dictionary.h +++ b/src/data/dictionary.h @@ -157,6 +157,7 @@ struct dict_callbacks void (*weight_changed) (struct dictionary *, int, void *); void (*filter_changed) (struct dictionary *, int, void *); void (*split_changed) (struct dictionary *, void *); + void (*var_display_width_changed) (struct dictionary *, int, void *); }; void dict_set_callbacks (struct dictionary *, const struct dict_callbacks *, diff --git a/src/data/vardict.h b/src/data/vardict.h index 35440a0d..dfde1bff 100644 --- a/src/data/vardict.h +++ b/src/data/vardict.h @@ -41,5 +41,6 @@ void var_clear_vardict (struct variable *); /* Called by variable.c, defined in dictionary.c. */ void dict_var_changed (const struct variable *v); void dict_var_resized (const struct variable *v, int delta); +void dict_var_display_width_changed (const struct variable *v); #endif /* data/vardict.h */ diff --git a/src/data/variable.c b/src/data/variable.c index d14237d9..ccbe65dc 100644 --- a/src/data/variable.c +++ b/src/data/variable.c @@ -778,9 +778,15 @@ var_get_display_width (const struct variable *v) /* Sets V's display width to DISPLAY_WIDTH. */ void -var_set_display_width (struct variable *v, int display_width) +var_set_display_width (struct variable *v, int new_width) { - v->display_width = display_width; + int old_width = v->display_width; + + v->display_width = new_width; + + if ( old_width != new_width) + dict_var_display_width_changed (v); + dict_var_changed (v); } diff --git a/src/libpspp/tower.c b/src/libpspp/tower.c index 02447d76..e8d253d0 100644 --- a/src/libpspp/tower.c +++ b/src/libpspp/tower.c @@ -30,12 +30,59 @@ static struct tower_node *next_node (const struct tower *, const struct tower_node *); static struct tower_node *prev_node (const struct tower *, const struct tower_node *); -static unsigned long int get_subtree_height (const struct abt_node *); +static unsigned long int get_subtree_size (const struct abt_node *); +static unsigned long int get_subtree_count (const struct abt_node *); static void reaugment_tower_node (struct abt_node *, const struct abt_node *, const struct abt_node *, const void *aux); +/* Returns the height of the bottom of the given tower NODE. + + The performance of this function is O(lg n) in the number of + nodes in the tower. It is often possible to avoid calling + this function, either by taking advantage of the NODE_START + parameter to tower_lookup or by incrementally keeping track of + height while iterating through a tower. In the former case + the asymptotic performance is no different, since tower_lookup + is also O(lg n), but in the latter case performance improves + from O(lg n) to O(1). */ +unsigned long int +tower_node_get_level (const struct tower_node *node) +{ + const struct abt_node *p = &node->abt_node; + unsigned long level = get_subtree_size (p->down[0]); + while (p->up != NULL) + { + if (p == p->up->down[1]) + level += (get_subtree_size (p->up->down[0]) + + abt_to_tower_node (p->up)->size); + p = p->up; + } + return level; +} + +/* Returns the index of the given tower NODE. + + The performance of this function is O(lg n) in the number of + nodes in the tower. It is often possible to avoid calling + this function by keeping track of the index while iterating + through a tower. Doing so when possible will improve + performance from O(lg n) to O(1). */ +unsigned long int +tower_node_get_index (const struct tower_node *node) +{ + const struct abt_node *p = &node->abt_node; + unsigned long index = get_subtree_count (p->down[0]); + while (p->up != NULL) + { + if (p == p->up->down[1]) + index += get_subtree_count (p->up->down[0]) + 1; + p = p->up; + } + return index; +} + /* Initializes T as an empty tower. */ void tower_init (struct tower *t) @@ -51,21 +98,28 @@ tower_is_empty (const struct tower *t) return t->abt.root == NULL; } +/* Returns the number of nodes in tower T. */ +unsigned long int +tower_count (const struct tower *t) +{ + return get_subtree_count (t->abt.root); +} + /* Returns the total height of tower T. */ unsigned long tower_height (const struct tower *t) { - return get_subtree_height (t->abt.root); + return get_subtree_size (t->abt.root); } -/* Inserts node NEW with the specified HEIGHT into T just below +/* Inserts node NEW with the specified SIZE into T just below node UNDER, or at the top of T if UNDER is a null pointer. */ void -tower_insert (struct tower *t, unsigned long height, struct tower_node *new, +tower_insert (struct tower *t, unsigned long size, struct tower_node *new, struct tower_node *under) { - assert (height > 0); - new->height = height; + assert (size > 0); + new->size = size; abt_insert_before (&t->abt, under ? &under->abt_node : NULL, &new->abt_node); t->cache_bottom = ULONG_MAX; @@ -81,13 +135,13 @@ tower_delete (struct tower *t, struct tower_node *node) return next; } -/* Changes the height of NODE in tower T to NEW_HEIGHT. */ +/* Changes the size of NODE in tower T to NEW_SIZE. */ void tower_resize (struct tower *t, struct tower_node *node, - unsigned long new_height) + unsigned long new_size) { - assert (new_height > 0); - node->height = new_height; + assert (new_size > 0); + node->size = new_size; abt_reaugmented (&t->abt, &node->abt_node); t->cache_bottom = ULONG_MAX; } @@ -135,7 +189,7 @@ tower_lookup (const struct tower *t_, assert (height < tower_height (t)); - if (height >= t->cache_bottom && height - t->cache_bottom < t->cache->height) + if (height >= t->cache_bottom && height - t->cache_bottom < t->cache->size) { *node_start = t->cache_bottom; return t->cache; @@ -145,8 +199,8 @@ tower_lookup (const struct tower *t_, p = t->abt.root; for (;;) { - unsigned long left_height = get_subtree_height (p->down[0]); - if (height < left_height) + unsigned long left_size = get_subtree_size (p->down[0]); + if (height < left_size) { /* Our goal height must lie within the left subtree. */ p = p->down[0]; @@ -155,11 +209,11 @@ tower_lookup (const struct tower *t_, { /* Our goal height cannot be in the left subtree. */ struct tower_node *node = abt_to_tower_node (p); - unsigned long int node_height = node->height; + unsigned long int node_size = node->size; - height -= left_height; - *node_start += left_height; - if (height < node_height) + height -= left_size; + *node_start += left_size; + if (height < node_size) { /* Our goal height is in P. */ t->cache = node; @@ -170,13 +224,40 @@ tower_lookup (const struct tower *t_, { /* Our goal height is in the right subtree. */ p = p->down[1]; - height -= node_height; - *node_start += node_height; + height -= node_size; + *node_start += node_size; } } } } +/* Returns the node with the given 0-based INDEX, which must be + less than the number of nodes in T (as returned by + tower_count). */ +struct tower_node * +tower_get (const struct tower *t_, unsigned long int index) +{ + struct tower *t = (struct tower *) t_; + struct abt_node *p; + + assert (index < tower_count (t)); + + p = t->abt.root; + for (;;) + { + unsigned long left_count = get_subtree_count (p->down[0]); + if (index < left_count) + p = p->down[0]; + else if (index == left_count) + return abt_to_tower_node (p); + else + { + p = p->down[1]; + index -= left_count + 1; + } + } +} + /* Returns the node at height 0 in tower T, or a null pointer if T is empty. */ struct tower_node * @@ -253,16 +334,24 @@ prev_node (const struct tower *t, const struct tower_node *node) return abt_to_tower_node_null (abt_prev (&t->abt, &node->abt_node)); } -/* Returns the total height of the nodes in the subtree rooted at +/* Returns the total size of the nodes in the subtree rooted at P, or 0 if P is null. */ static unsigned long int -get_subtree_height (const struct abt_node *p) +get_subtree_size (const struct abt_node *p) +{ + return p != NULL ? abt_to_tower_node (p)->subtree_size : 0; +} + +/* Returns the total number of nodes in the subtree rooted at P, + or 0 if P is null. */ +static unsigned long int +get_subtree_count (const struct abt_node *p) { - return p != NULL ? abt_to_tower_node (p)->subtree_height : 0; + return p != NULL ? abt_to_tower_node (p)->subtree_count : 0; } -/* Recalculates the subtree_height of NODE based on its LEFT and - RIGHT children's subtree_heights. */ +/* Recalculates the subtree_size of NODE based on its LEFT and + RIGHT children's subtree_sizes. */ static void reaugment_tower_node (struct abt_node *node_, const struct abt_node *left, @@ -270,9 +359,18 @@ reaugment_tower_node (struct abt_node *node_, const void *aux UNUSED) { struct tower_node *node = abt_to_tower_node (node_); - node->subtree_height = node->height; - if (left != NULL) - node->subtree_height += abt_to_tower_node (left)->subtree_height; - if (right != NULL) - node->subtree_height += abt_to_tower_node (right)->subtree_height; + node->subtree_size = node->size; + node->subtree_count = 1; + if (left != NULL) + { + struct tower_node *left_node = abt_to_tower_node (left); + node->subtree_size += left_node->subtree_size; + node->subtree_count += left_node->subtree_count; + } + if (right != NULL) + { + struct tower_node *right_node = abt_to_tower_node (right); + node->subtree_size += right_node->subtree_size; + node->subtree_count += right_node->subtree_count; + } } diff --git a/src/libpspp/tower.h b/src/libpspp/tower.h index 55184e51..246984a2 100644 --- a/src/libpspp/tower.h +++ b/src/libpspp/tower.h @@ -33,14 +33,18 @@ This is the analogy behind this data structure. Each node in the data structure has a "thickness", which is actually called - the node's "height" because "thickness" is just too awkward a + the node's "size" because "thickness" is just too awkward a name. The primary way to look up nodes is by a height from the bottom of the tower; any height within a node retrieves that node, not just the distance to the bottom of the node. You can insert a new node between any two existing nodes, or at either end, which shifts up the height of all the nodes above it. You can also delete any node, which shifts down the - height of all the nodes above it. */ + height of all the nodes above it. + + The tower data structure also implements efficient access to + nodes by index, i.e. by 0-based count of nodes from the bottom + of the tower. */ #ifndef LIBPSPP_TOWER_H #define LIBPSPP_TOWER_H @@ -58,17 +62,21 @@ struct tower_node { struct abt_node abt_node; /* ABT node. */ - unsigned long int subtree_height; /* Node's plus descendants' heights. */ - unsigned long int height; /* Height. */ + unsigned long int subtree_size; /* Node size plus descendants' sizes. */ + unsigned long int size; /* Size. */ + unsigned long int subtree_count; /* Number of descendants, plus 1. */ }; -/* Returns the height of a tower node. */ +/* Returns the size of a tower node. */ static inline unsigned long -tower_node_get_height (const struct tower_node *node) +tower_node_get_size (const struct tower_node *node) { - return node->height; + return node->size; } +unsigned long int tower_node_get_level (const struct tower_node *); +unsigned long int tower_node_get_index (const struct tower_node *); + /* A tower. */ struct tower { @@ -80,13 +88,14 @@ struct tower void tower_init (struct tower *); bool tower_is_empty (const struct tower *); +unsigned long int tower_count (const struct tower *); unsigned long int tower_height (const struct tower *); -void tower_insert (struct tower *, unsigned long int height, +void tower_insert (struct tower *, unsigned long int size, struct tower_node *new, struct tower_node *under); struct tower_node *tower_delete (struct tower *, struct tower_node *); void tower_resize (struct tower *, struct tower_node *, - unsigned long int new_height); + unsigned long int new_size); void tower_splice (struct tower *dst, struct tower_node *under, struct tower *src, struct tower_node *first, struct tower_node *last); @@ -94,6 +103,7 @@ void tower_splice (struct tower *dst, struct tower_node *under, struct tower_node *tower_lookup (const struct tower *, unsigned long int level, unsigned long int *node_start); +struct tower_node *tower_get (const struct tower *, unsigned long int index); struct tower_node *tower_first (const struct tower *); struct tower_node *tower_last (const struct tower *); struct tower_node *tower_next (const struct tower *, diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c index 072e55ba..2e1dee89 100644 --- a/src/ui/gui/psppire-data-editor.c +++ b/src/ui/gui/psppire-data-editor.c @@ -21,7 +21,6 @@ #include "psppire-data-editor.h" #include "psppire-var-sheet.h" -#include #include #include "psppire-data-store.h" #include "helper.h" @@ -199,6 +198,81 @@ enum PROP_SPLIT_WINDOW }; + +#define WIDTH_OF_M 10 + +static void +new_variables_callback (PsppireDict *dict, gpointer data) +{ + gint v, i; + PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); + + for (i = 0 ; i < 4 ; ++i) + { + PsppireAxis *haxis; + g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL); + + psppire_axis_clear (haxis); + + for (v = 0 ; v < psppire_dict_get_var_cnt (dict); ++v) + { + const struct variable *var = psppire_dict_get_variable (dict, v); + + psppire_axis_append (haxis, 10 * var_get_display_width (var)); + } + } +} + +static void +insert_variable_callback (PsppireDict *dict, gint x, gpointer data) +{ + gint i; + PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); + + for (i = 0 ; i < 4 ; ++i) + { + const struct variable *var = psppire_dict_get_variable (dict, x); + PsppireAxis *haxis; + g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL); + + psppire_axis_insert (haxis, WIDTH_OF_M * var_get_display_width (var), x); + } +} + + +static void +delete_variable_callback (PsppireDict *dict, gint posn, gint x UNUSED, gint y UNUSED, gpointer data) +{ + gint i; + PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); + + for (i = 0 ; i < 4 ; ++i) + { + PsppireAxis *haxis; + g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL); + + psppire_axis_remove (haxis, posn); + } +} + + +static void +rewidth_variable_callback (PsppireDict *dict, gint posn, gpointer data) +{ + gint i; + PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data); + + for (i = 0 ; i < 4 ; ++i) + { + const struct variable *var = psppire_dict_get_variable (dict, posn); + PsppireAxis *haxis; + g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL); + + psppire_axis_resize_unit (haxis, WIDTH_OF_M * var_get_display_width (var), posn); + } +} + + static void psppire_data_editor_set_property (GObject *object, guint prop_id, @@ -221,9 +295,14 @@ psppire_data_editor_set_property (GObject *object, for (i = 0 ; i < 4 ; ++i ) g_object_set (de->data_sheet[i], "row-geometry", de->data_store, - "column-geometry", de->data_store, "model", de->data_store, NULL); + + g_signal_connect (de->data_store->dict, "backend-changed", G_CALLBACK (new_variables_callback), de); + g_signal_connect (de->data_store->dict, "variable-inserted", G_CALLBACK (insert_variable_callback), de); + g_signal_connect (de->data_store->dict, "variable-deleted", G_CALLBACK (delete_variable_callback), de); + // g_signal_connect (de->data_store->dict, "variable-changed", G_CALLBACK (alter_variable_callback), de); + g_signal_connect (de->data_store->dict, "variable-display-width-changed", G_CALLBACK (rewidth_variable_callback), de); break; case PROP_VAR_STORE: if ( de->var_store) g_object_unref (de->var_store); @@ -613,6 +692,7 @@ static void init_sheet (PsppireDataEditor *de, int i, GtkAdjustment *hadj, GtkAdjustment *vadj) { + PsppireAxis *haxis = psppire_axis_new (); de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj); de->data_sheet[i] = gtk_sheet_new (NULL, NULL, NULL); @@ -622,6 +702,10 @@ init_sheet (PsppireDataEditor *de, int i, "shadow-type", GTK_SHADOW_ETCHED_IN, NULL); + g_object_set (de->data_sheet[i], + "horizontal-axis", haxis, + NULL); + gtk_container_add (GTK_CONTAINER (de->sheet_bin[i]), de->data_sheet[i]); g_signal_connect (de->data_sheet[i], "traverse", @@ -786,16 +870,10 @@ GtkWidget* psppire_data_editor_new (PsppireVarStore *var_store, PsppireDataStore *data_store) { - GtkWidget *widget; - - widget = g_object_new (PSPPIRE_DATA_EDITOR_TYPE, - "var-store", var_store, - "data-store", data_store, - NULL); - - - - return widget; + return g_object_new (PSPPIRE_DATA_EDITOR_TYPE, + "var-store", var_store, + "data-store", data_store, + NULL); } diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index 9f7e4075..9835d307 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2006 Free Software Foundation + Copyright (C) 2006, 2008 Free Software Foundation This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -45,7 +44,6 @@ static void psppire_data_store_init (PsppireDataStore *data_store); static void psppire_data_store_class_init (PsppireDataStoreClass *class); static void psppire_data_store_sheet_model_init (GSheetModelIface *iface); -static void psppire_data_store_sheet_column_init (GSheetColumnIface *iface); static void psppire_data_store_sheet_row_init (GSheetRowIface *iface); static void psppire_data_store_finalize (GObject *object); @@ -94,13 +92,6 @@ psppire_data_store_get_type (void) NULL }; - static const GInterfaceInfo sheet_column_info = - { - (GInterfaceInitFunc) psppire_data_store_sheet_column_init, - NULL, - NULL - }; - static const GInterfaceInfo sheet_row_info = { (GInterfaceInitFunc) psppire_data_store_sheet_row_init, @@ -116,10 +107,6 @@ psppire_data_store_get_type (void) G_TYPE_SHEET_MODEL, &sheet_model_info); - g_type_add_interface_static (data_store_type, - G_TYPE_SHEET_COLUMN, - &sheet_column_info); - g_type_add_interface_static (data_store_type, G_TYPE_SHEET_ROW, &sheet_row_info); @@ -217,6 +204,11 @@ psppire_data_store_set_string_wrapper (GSheetModel *model, +static gchar * get_column_subtitle (const GSheetModel *model, gint col); +static gchar * get_column_button_label (const GSheetModel *model, gint col); +static gboolean get_column_sensitivity (const GSheetModel *model, gint col); +static GtkJustification get_column_justification (const GSheetModel *model, gint col); + static void psppire_data_store_sheet_model_init (GSheetModelIface *iface) @@ -233,6 +225,11 @@ psppire_data_store_sheet_model_init (GSheetModelIface *iface) iface->get_cell_border = NULL; iface->get_column_count = psppire_data_store_get_var_count; iface->get_row_count = psppire_data_store_get_case_count_wrapper; + + iface->get_column_subtitle = get_column_subtitle; + iface->get_column_title = get_column_button_label; + iface->get_column_sensitivity = get_column_sensitivity; + iface->get_column_justification = get_column_justification; } static void @@ -293,10 +290,12 @@ delete_variable_callback (GObject *obj, gint dict_index, { PsppireDataStore *store = PSPPIRE_DATA_STORE (data); +#if AXIS_TRANSITION g_sheet_model_columns_deleted (G_SHEET_MODEL (store), dict_index, 1); g_sheet_column_columns_changed (G_SHEET_COLUMN (store), dict_index, -1); +#endif } @@ -305,6 +304,7 @@ variable_changed_callback (GObject *obj, gint var_num, gpointer data) { PsppireDataStore *store = PSPPIRE_DATA_STORE (data); +#if AXIS_TRANSITION g_sheet_column_columns_changed (G_SHEET_COLUMN (store), var_num, 1); @@ -312,6 +312,7 @@ variable_changed_callback (GObject *obj, gint var_num, gpointer data) g_sheet_model_range_changed (G_SHEET_MODEL (store), -1, var_num, -1, var_num); +#endif } static void @@ -340,8 +341,10 @@ insert_variable_callback (GObject *obj, gint var_num, gpointer data) psppire_case_file_insert_values (store->case_file, 1, posn); +#if AXIS_TRANSITION g_sheet_column_columns_changed (G_SHEET_COLUMN (store), var_num, 1); +#endif g_sheet_model_columns_inserted (G_SHEET_MODEL (store), var_num, 1); } @@ -485,8 +488,9 @@ psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *di /* The entire model has changed */ g_sheet_model_range_changed (G_SHEET_MODEL (data_store), -1, -1, -1, -1); +#if AXIS_TRANSITION g_sheet_column_columns_changed (G_SHEET_COLUMN (data_store), 0, -1); - +#endif if ( data_store->dict ) for (i = 0 ; i < n_dict_signals; ++i ) @@ -760,6 +764,7 @@ psppire_data_store_get_reader (PsppireDataStore *ds) /* Column related funcs */ +#if AXIS_TRANSITION static glong geometry_get_column_count (const GSheetColumn *geom) { @@ -799,88 +804,11 @@ geometry_set_width (GSheetColumn *geom, glong unit, gint width) var_set_display_width (v, width / ds->width_of_m ); } - - -static GtkJustification -geometry_get_justification (const GSheetColumn *geom, glong unit) -{ - PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom); - const struct variable *pv ; - - - if ( unit >= psppire_dict_get_var_cnt (ds->dict) ) - return GTK_JUSTIFY_LEFT; - - pv = psppire_dict_get_variable (ds->dict, unit); - - return (var_get_alignment (pv) == ALIGN_LEFT ? GTK_JUSTIFY_LEFT - : var_get_alignment (pv) == ALIGN_RIGHT ? GTK_JUSTIFY_RIGHT - : GTK_JUSTIFY_CENTER); -} +#endif static const gchar null_var_name[]=N_("var"); -static gchar * -geometry_get_column_button_label (const GSheetColumn *geom, glong unit) -{ - gchar *text; - struct variable *pv ; - PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom); - - if ( unit >= psppire_dict_get_var_cnt (ds->dict) ) - return g_locale_to_utf8 (null_var_name, -1, 0, 0, 0); - - pv = psppire_dict_get_variable (ds->dict, unit); - - text = pspp_locale_to_utf8 (var_get_name (pv), -1, 0); - - return text; -} - - -static gchar * -geometry_get_column_subtitle (const GSheetColumn *geom, glong unit) -{ - gchar *text; - const struct variable *v ; - PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom); - - if ( unit >= psppire_dict_get_var_cnt (ds->dict) ) - return NULL; - - v = psppire_dict_get_variable (ds->dict, unit); - - if ( ! var_has_label (v)) - return NULL; - - text = pspp_locale_to_utf8 (var_get_label (v), -1, 0); - - return text; -} - - -static gboolean -geometry_get_sensitivity (const GSheetColumn *geom, glong unit) -{ - PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom); - - return (unit < psppire_dict_get_var_cnt (ds->dict)); -} - - -static void -psppire_data_store_sheet_column_init (GSheetColumnIface *iface) -{ - iface->get_column_count = geometry_get_column_count; - iface->get_width = geometry_get_width; - iface->set_width = geometry_set_width; - iface->get_sensitivity = geometry_get_sensitivity; - iface->get_justification = geometry_get_justification; - iface->get_button_label = geometry_get_column_button_label; - iface->get_subtitle = geometry_get_column_subtitle; -} - /* Row related funcs */ @@ -959,3 +887,73 @@ psppire_data_store_sheet_row_init (GSheetRowIface *iface) iface->pixel_to_row = geometry_pixel_to_row; iface->get_button_label = geometry_get_row_button_label; } + + + + +/* Column related stuff */ + +static gchar * +get_column_subtitle (const GSheetModel *model, gint col) +{ + gchar *text; + const struct variable *v ; + PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); + + if ( col >= psppire_dict_get_var_cnt (ds->dict) ) + return NULL; + + v = psppire_dict_get_variable (ds->dict, col); + + if ( ! var_has_label (v)) + return NULL; + + text = pspp_locale_to_utf8 (var_get_label (v), -1, 0); + + return text; +} + +static gchar * +get_column_button_label (const GSheetModel *model, gint col) +{ + gchar *text; + struct variable *pv ; + PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); + + if ( col >= psppire_dict_get_var_cnt (ds->dict) ) + return g_locale_to_utf8 (null_var_name, -1, 0, 0, 0); + + pv = psppire_dict_get_variable (ds->dict, col); + + text = pspp_locale_to_utf8 (var_get_name (pv), -1, 0); + + return text; +} + +static gboolean +get_column_sensitivity (const GSheetModel *model, gint col) +{ + PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); + + return (col < psppire_dict_get_var_cnt (ds->dict)); +} + + + +static GtkJustification +get_column_justification (const GSheetModel *model, gint col) +{ + PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); + const struct variable *pv ; + + if ( col >= psppire_dict_get_var_cnt (ds->dict) ) + return GTK_JUSTIFY_LEFT; + + pv = psppire_dict_get_variable (ds->dict, col); + + return (var_get_alignment (pv) == ALIGN_LEFT ? GTK_JUSTIFY_LEFT + : var_get_alignment (pv) == ALIGN_RIGHT ? GTK_JUSTIFY_RIGHT + : GTK_JUSTIFY_CENTER); +} + + diff --git a/src/ui/gui/psppire-data-store.h b/src/ui/gui/psppire-data-store.h index 06a5e403..8f30afa4 100644 --- a/src/ui/gui/psppire-data-store.h +++ b/src/ui/gui/psppire-data-store.h @@ -17,7 +17,6 @@ #ifndef __PSPPIRE_DATA_STORE_H__ #define __PSPPIRE_DATA_STORE_H__ -#include #include "psppire-dict.h" #include "psppire-case-file.h" diff --git a/src/ui/gui/psppire-dict.c b/src/ui/gui/psppire-dict.c index e6f1373a..8f7fed61 100644 --- a/src/ui/gui/psppire-dict.c +++ b/src/ui/gui/psppire-dict.c @@ -30,16 +30,6 @@ #include "helper.h" #include "message-dialog.h" -/* --- prototypes --- */ -static void psppire_dict_class_init (PsppireDictClass *class); -static void psppire_dict_init (PsppireDict *dict); -static void psppire_dict_finalize (GObject *object); - -static void dictionary_tree_model_init (GtkTreeModelIface *iface); - - -/* --- variables --- */ -static GObjectClass *parent_class = NULL; enum { BACKEND_CHANGED, @@ -48,6 +38,7 @@ enum { VARIABLE_RESIZED, VARIABLE_INSERTED, VARIABLE_DELETED, + VARIABLE_DISPLAY_WIDTH_CHANGED, WEIGHT_CHANGED, FILTER_CHANGED, @@ -55,6 +46,18 @@ enum { n_SIGNALS }; + +/* --- prototypes --- */ +static void psppire_dict_class_init (PsppireDictClass *class); +static void psppire_dict_init (PsppireDict *dict); +static void psppire_dict_finalize (GObject *object); + +static void dictionary_tree_model_init (GtkTreeModelIface *iface); + + +/* --- variables --- */ +static GObjectClass *parent_class = NULL; + static guint signals [n_SIGNALS]; /* --- functions --- */ @@ -93,8 +96,6 @@ psppire_dict_get_type (void) g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL, &tree_model_info); - - } return object_type; @@ -172,6 +173,17 @@ psppire_dict_class_init (PsppireDictClass *class) G_TYPE_INT, G_TYPE_INT); + signals [VARIABLE_DISPLAY_WIDTH_CHANGED] = + g_signal_new ("variable-display-width-changed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); + signals [WEIGHT_CHANGED] = g_signal_new ("weight-changed", @@ -223,7 +235,10 @@ psppire_dict_finalize (GObject *object) static void addcb (struct dictionary *d, int idx, void *pd) { - g_signal_emit (pd, signals [VARIABLE_INSERTED], 0, idx); + PsppireDict *dict = PSPPIRE_DICT (pd); + + if ( ! dict->disable_insert_signal) + g_signal_emit (dict, signals [VARIABLE_INSERTED], 0, idx); } static void @@ -264,6 +279,13 @@ split_changed_callback (struct dictionary *d, void *pd) g_signal_emit (pd, signals [SPLIT_CHANGED], 0); } +static void +variable_display_width_callback (struct dictionary *d, int idx, void *pd) +{ + g_signal_emit (pd, signals [VARIABLE_DISPLAY_WIDTH_CHANGED], 0, idx); +} + + static const struct dict_callbacks gui_callbacks = { @@ -273,13 +295,15 @@ static const struct dict_callbacks gui_callbacks = resize_cb, weight_changed_callback, filter_changed_callback, - split_changed_callback + split_changed_callback, + variable_display_width_callback }; static void psppire_dict_init (PsppireDict *psppire_dict) { psppire_dict->stamp = g_random_int (); + psppire_dict->disable_insert_signal = FALSE; } /** @@ -349,9 +373,15 @@ psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name) if ( ! name ) name = auto_generate_var_name (d); + d->disable_insert_signal = TRUE; + var = dict_create_var (d->dict, name, 0); dict_reorder_var (d->dict, var, idx); + + d->disable_insert_signal = FALSE; + + g_signal_emit (d, signals[VARIABLE_INSERTED], 0, idx); } /* Delete N variables beginning at FIRST */ diff --git a/src/ui/gui/psppire-dict.h b/src/ui/gui/psppire-dict.h index 1bf8bd35..534f0707 100644 --- a/src/ui/gui/psppire-dict.h +++ b/src/ui/gui/psppire-dict.h @@ -38,7 +38,6 @@ G_BEGIN_DECLS #define PSPPIRE_DICT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_DICT, PsppireDictClass)) - /* --- typedefs & structures --- */ typedef struct _PsppireDict PsppireDict; typedef struct _PsppireDictClass PsppireDictClass; @@ -50,6 +49,7 @@ struct _PsppireDict GObject parent; struct dictionary *dict; + gboolean disable_insert_signal; /* For GtkTreeModelIface */ gint stamp; }; diff --git a/src/ui/gui/psppire-var-sheet.c b/src/ui/gui/psppire-var-sheet.c index 0708bf3e..03365202 100644 --- a/src/ui/gui/psppire-var-sheet.c +++ b/src/ui/gui/psppire-var-sheet.c @@ -19,7 +19,7 @@ #include #include "helper.h" -#include + #include "customentry.h" #include #include "psppire-var-store.h" @@ -95,20 +95,6 @@ struct column_parameters gint width ; }; -static const struct column_parameters column_def[] = { - { N_("Name"), 80}, - { N_("Type"), 100}, - { N_("Width"), 57}, - { N_("Decimals"),91}, - { N_("Label"), 95}, - { N_("Values"), 103}, - { N_("Missing"), 95}, - { N_("Columns"), 80}, - { N_("Align"), 69}, - { N_("Measure"), 99}, -}; - - #define n_ALIGNMENTS 3 const gchar *const alignments[n_ALIGNMENTS + 1]={ @@ -502,8 +488,7 @@ var_sheet_change_active_cell (PsppireVarSheet *vs, static void psppire_var_sheet_init (PsppireVarSheet *vs) { - gint i; - GObject *geo = g_sheet_hetero_column_new (75, PSPPIRE_VAR_STORE_n_COLS); + // gint i; GladeXML *xml = XML_NEW ("data-editor.glade"); vs->val_labs_dialog = val_labs_dialog_create (xml); @@ -515,16 +500,13 @@ psppire_var_sheet_init (PsppireVarSheet *vs) vs->dispose_has_run = FALSE; vs->may_create_vars = TRUE; +#if 0 for (i = 0 ; i < PSPPIRE_VAR_STORE_n_COLS ; ++i ) { - g_sheet_hetero_column_set_button_label (G_SHEET_HETERO_COLUMN (geo), i, - gettext (column_def[i].label)); - g_sheet_hetero_column_set_width (G_SHEET_HETERO_COLUMN (geo), i, column_def[i].width); } - - g_object_set (vs, "column-geometry", geo, NULL); +#endif g_signal_connect (vs, "activate", G_CALLBACK (var_sheet_change_active_cell), @@ -535,8 +517,32 @@ psppire_var_sheet_init (PsppireVarSheet *vs) } +static const struct column_parameters column_def[] = { + { N_("Name"), 80}, + { N_("Type"), 100}, + { N_("Width"), 57}, + { N_("Decimals"),91}, + { N_("Label"), 95}, + { N_("Values"), 103}, + { N_("Missing"), 95}, + { N_("Columns"), 80}, + { N_("Align"), 69}, + { N_("Measure"), 99}, +}; + GtkWidget* psppire_var_sheet_new (void) { - return GTK_WIDGET (g_object_new (psppire_var_sheet_get_type (), NULL)); + gint i; + PsppireAxis *a = psppire_axis_new (); + GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL); + + for (i = 0 ; i < 10 ; ++i) + psppire_axis_append (a, column_def[i].width); + + g_object_set (w, + "horizontal-axis", a, + NULL); + + return w; } diff --git a/src/ui/gui/psppire-var-store.c b/src/ui/gui/psppire-var-store.c index efe1ae0d..4575bd3b 100644 --- a/src/ui/gui/psppire-var-store.c +++ b/src/ui/gui/psppire-var-store.c @@ -329,7 +329,7 @@ psppire_var_store_get_font_desc (const GSheetModel *model, } - +static gchar *get_column_title (const GSheetModel *model, gint col); static void psppire_var_store_sheet_model_init (GSheetModelIface *iface) @@ -347,9 +347,9 @@ psppire_var_store_sheet_model_init (GSheetModelIface *iface) iface->get_font_desc = psppire_var_store_get_font_desc; iface->get_cell_border = NULL; iface->get_justification = NULL; -} - + iface->get_column_title = get_column_title; +} /** * psppire_var_store_new: @@ -846,3 +846,27 @@ psppire_var_store_sheet_row_init (GSheetRowIface *iface) iface->get_button_label = geometry_get_button_label; } + + + +static const gchar *column_titles[] = { + N_("Name"), + N_("Type"), + N_("Width"), + N_("Decimals"), + N_("Label"), + N_("Values"), + N_("Missing"), + N_("Columns"), + N_("Align"), + N_("Measure"), +}; + + +static gchar * +get_column_title (const GSheetModel *model, gint col) +{ + if ( col >= 10) + return NULL; + return g_strdup (gettext (column_titles[col])); +} diff --git a/src/ui/gui/psppire-var-store.h b/src/ui/gui/psppire-var-store.h index a4782efc..72c9192c 100644 --- a/src/ui/gui/psppire-var-store.h +++ b/src/ui/gui/psppire-var-store.h @@ -17,7 +17,6 @@ #ifndef __PSPPIRE_VAR_STORE_H__ #define __PSPPIRE_VAR_STORE_H__ -#include #include "psppire-dict.h" #include diff --git a/tests/libpspp/tower-test.c b/tests/libpspp/tower-test.c index 504e19f4..c603c3a8 100644 --- a/tests/libpspp/tower-test.c +++ b/tests/libpspp/tower-test.c @@ -245,7 +245,7 @@ next_composition (int n, int *k, int parts[]) /* A block expected to be found in a tower. */ struct expected_block { - int height; /* Expected height of bottom of block. */ + int size; /* Expected thickness of block. */ int x; /* Expected value for `x' member. */ }; @@ -259,6 +259,7 @@ check_tower (struct tower *t, struct tower_node *node; size_t i; + check (tower_count (t) == block_cnt); check (tower_is_empty (t) == (block_cnt == 0)); total_height = 0; @@ -266,7 +267,7 @@ check_tower (struct tower *t, { unsigned long int level; for (level = total_height; - level < total_height + blocks[i].height; + level < total_height + blocks[i].size; level++) { struct tower_node *found; @@ -275,8 +276,11 @@ check_tower (struct tower *t, check (found != NULL); check (tower_node_to_block (found)->x == blocks[i].x); check (block_start == total_height); + check (tower_node_get_level (found) == total_height); + check (tower_node_get_index (found) == i); + check (tower_get (t, i) == found); } - total_height += blocks[i].height; + total_height += blocks[i].size; } check (tower_height (t) == total_height); @@ -284,7 +288,7 @@ check_tower (struct tower *t, node != NULL; node = tower_next (t, node), i++) { - check (tower_node_get_height (node) == blocks[i].height); + check (tower_node_get_size (node) == blocks[i].size); check (tower_node_to_block (node)->x == blocks[i].x); } check (i == block_cnt); @@ -293,7 +297,7 @@ check_tower (struct tower *t, node != NULL; node = tower_prev (t, node), i--) { - check (tower_node_get_height (node) == blocks[i].height); + check (tower_node_get_size (node) == blocks[i].size); check (tower_node_to_block (node)->x == blocks[i].x); } check (i == SIZE_MAX); @@ -312,19 +316,19 @@ test_insert (void) { unsigned int composition_cnt; struct expected_block *expected; - int *heights; + int *sizes; int block_cnt; int *order; struct block *blocks; expected = xnmalloc (cnt, sizeof *expected); - heights = xnmalloc (cnt, sizeof *heights); + sizes = xnmalloc (cnt, sizeof *sizes); order = xnmalloc (cnt, sizeof *order); blocks = xnmalloc (cnt, sizeof *blocks); block_cnt = 0; composition_cnt = 0; - while (next_composition (cnt, &block_cnt, heights)) + while (next_composition (cnt, &block_cnt, sizes)) { int i, j; unsigned int permutation_cnt; @@ -338,7 +342,7 @@ test_insert (void) struct tower t; /* Inserts the block_cnt blocks with the given - heights[] into T in the order given by order[]. */ + sizes[] into T in the order given by order[]. */ tower_init (&t); for (i = 0; i < block_cnt; i++) { @@ -354,14 +358,14 @@ test_insert (void) && (under == NULL || under->x > order[j])) under = &blocks[order[j]]; - tower_insert (&t, heights[idx], &blocks[idx].node, + tower_insert (&t, sizes[idx], &blocks[idx].node, under != NULL ? &under->node : NULL); } /* Check that the result is what we expect. */ for (i = 0; i < block_cnt; i++) { - expected[i].height = heights[i]; + expected[i].size = sizes[i]; expected[i].x = i; } check_tower (&t, expected, block_cnt); @@ -375,14 +379,14 @@ test_insert (void) check (composition_cnt == 1 << (cnt - 1)); free (expected); - free (heights); + free (sizes); free (order); free (blocks); } } /* Tests deleting blocks from towers that initially contain all - possible sets of block heights into a tower in all possible + possible sets of block sizes into a tower in all possible orders, up to a specified maximum tower height. */ static void test_delete (void) @@ -394,19 +398,19 @@ test_delete (void) { unsigned int composition_cnt; struct expected_block *expected; - int *heights; + int *sizes; int block_cnt; int *order; struct block *blocks; expected = xnmalloc (cnt, sizeof *expected); - heights = xnmalloc (cnt, sizeof *heights); + sizes = xnmalloc (cnt, sizeof *sizes); order = xnmalloc (cnt, sizeof *order); blocks = xnmalloc (cnt, sizeof *blocks); block_cnt = 0; composition_cnt = 0; - while (next_composition (cnt, &block_cnt, heights)) + while (next_composition (cnt, &block_cnt, sizes)) { int i; unsigned int permutation_cnt; @@ -424,9 +428,9 @@ test_delete (void) for (i = 0; i < block_cnt; i++) { blocks[i].x = i; - tower_insert (&t, heights[i], &blocks[i].node, NULL); + tower_insert (&t, sizes[i], &blocks[i].node, NULL); expected[i].x = i; - expected[i].height = heights[i]; + expected[i].size = sizes[i]; } check_tower (&t, expected, block_cnt); @@ -459,14 +463,14 @@ test_delete (void) check (composition_cnt == 1 << (cnt - 1)); free (expected); - free (heights); + free (sizes); free (order); free (blocks); } } -/* Tests towers containing all possible block heights, resizing - the blocks to all possible heights that conserve the total +/* Tests towers containing all possible block sizes, resizing + the blocks to all possible sizes that conserve the total tower height, up to a maximum total tower height. */ static void test_resize (void) @@ -478,27 +482,27 @@ test_resize (void) { unsigned int composition_cnt; struct expected_block *expected; - int *heights, *new_heights; + int *sizes, *new_sizes; int block_cnt; int *order; struct block *blocks; expected = xnmalloc (cnt, sizeof *expected); - heights = xnmalloc (cnt, sizeof *heights); - new_heights = xnmalloc (cnt, sizeof *new_heights); + sizes = xnmalloc (cnt, sizeof *sizes); + new_sizes = xnmalloc (cnt, sizeof *new_sizes); order = xnmalloc (cnt, sizeof *order); blocks = xnmalloc (cnt, sizeof *blocks); block_cnt = 0; composition_cnt = 0; - while (next_composition (cnt, &block_cnt, heights)) + while (next_composition (cnt, &block_cnt, sizes)) { int i; unsigned int resizes = 0; - for (resizes = 0, first_k_composition (cnt, block_cnt, new_heights); + for (resizes = 0, first_k_composition (cnt, block_cnt, new_sizes); (resizes == 0 - || next_k_composition (cnt, block_cnt, new_heights)); + || next_k_composition (cnt, block_cnt, new_sizes)); resizes++) { struct tower t; @@ -508,18 +512,18 @@ test_resize (void) for (i = 0; i < block_cnt; i++) { blocks[i].x = i; - tower_insert (&t, heights[i], &blocks[i].node, NULL); + tower_insert (&t, sizes[i], &blocks[i].node, NULL); expected[i].x = i; - expected[i].height = heights[i]; + expected[i].size = sizes[i]; } check_tower (&t, expected, block_cnt); /* Resize all the blocks. */ for (i = 0; i < block_cnt; i++) { - if (expected[i].height != new_heights[i] || rand () % 2) - tower_resize (&t, &blocks[i].node, new_heights[i]); - expected[i].height = new_heights[i]; + if (expected[i].size != new_sizes[i] || rand () % 2) + tower_resize (&t, &blocks[i].node, new_sizes[i]); + expected[i].size = new_sizes[i]; } check_tower (&t, expected, block_cnt); } @@ -530,8 +534,8 @@ test_resize (void) check (composition_cnt == 1 << (cnt - 1)); free (expected); - free (new_heights); - free (heights); + free (new_sizes); + free (sizes); free (order); free (blocks); } @@ -549,20 +553,20 @@ test_splice_out (void) { unsigned int composition_cnt; struct expected_block *expected; - int *heights, *new_heights; + int *sizes, *new_sizes; int block_cnt; int *order; struct block *blocks; expected = xnmalloc (cnt, sizeof *expected); - heights = xnmalloc (cnt, sizeof *heights); - new_heights = xnmalloc (cnt, sizeof *new_heights); + sizes = xnmalloc (cnt, sizeof *sizes); + new_sizes = xnmalloc (cnt, sizeof *new_sizes); order = xnmalloc (cnt, sizeof *order); blocks = xnmalloc (cnt, sizeof *blocks); block_cnt = 0; composition_cnt = 0; - while (next_composition (cnt, &block_cnt, heights)) + while (next_composition (cnt, &block_cnt, sizes)) { int i, j; @@ -579,9 +583,9 @@ test_splice_out (void) for (k = 0; k < block_cnt; k++) { blocks[k].x = k; - tower_insert (&src, heights[k], &blocks[k].node, NULL); + tower_insert (&src, sizes[k], &blocks[k].node, NULL); expected[k].x = k; - expected[k].height = heights[k]; + expected[k].size = sizes[k]; } check_tower (&src, expected, block_cnt); @@ -598,8 +602,8 @@ test_splice_out (void) check (composition_cnt == 1 << (cnt - 1)); free (expected); - free (new_heights); - free (heights); + free (new_sizes); + free (sizes); free (order); free (blocks); } @@ -617,20 +621,20 @@ test_splice_in (void) { unsigned int composition_cnt; struct expected_block *expected; - int *heights, *new_heights; + int *sizes, *new_sizes; int block_cnt; int *order; struct block *blocks; expected = xnmalloc (cnt, sizeof *expected); - heights = xnmalloc (cnt, sizeof *heights); - new_heights = xnmalloc (cnt, sizeof *new_heights); + sizes = xnmalloc (cnt, sizeof *sizes); + new_sizes = xnmalloc (cnt, sizeof *new_sizes); order = xnmalloc (cnt, sizeof *order); blocks = xnmalloc (cnt, sizeof *blocks); block_cnt = 0; composition_cnt = 0; - while (next_composition (cnt, &block_cnt, heights)) + while (next_composition (cnt, &block_cnt, sizes)) { int i, j; @@ -648,9 +652,9 @@ test_splice_in (void) { blocks[k].x = k; tower_insert (k >= i && k < j ? &src : &dst, - heights[k], &blocks[k].node, NULL); + sizes[k], &blocks[k].node, NULL); expected[k].x = k; - expected[k].height = heights[k]; + expected[k].size = sizes[k]; } /* Splice SRC into DST. */ @@ -663,8 +667,8 @@ test_splice_in (void) check (composition_cnt == 1 << (cnt - 1)); free (expected); - free (new_heights); - free (heights); + free (new_sizes); + free (sizes); free (order); free (blocks); }