Replaced implementation of psppire-axis.
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 6 Dec 2008 00:07:42 +0000 (09:07 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 6 Dec 2008 00:07:42 +0000 (09:07 +0900)
Deleted psppire-axis-hetero.* and psppire-axis-uniform.* and
replaced with psppire-axis-impl.[ch] which combines the benefits
of both.

lib/gtksheet/automake.mk
lib/gtksheet/psppire-axis-hetero.c [deleted file]
lib/gtksheet/psppire-axis-hetero.h [deleted file]
lib/gtksheet/psppire-axis-impl.c [new file with mode: 0644]
lib/gtksheet/psppire-axis-impl.h [new file with mode: 0644]
lib/gtksheet/psppire-axis-uniform.c [deleted file]
lib/gtksheet/psppire-axis-uniform.h [deleted file]
lib/gtksheet/psppire-axis.h
src/ui/gui/psppire-data-editor.c
src/ui/gui/psppire-var-sheet.c

index 1ad14a7f63ef360bd223a88cf0b6533434b4c9e8..25775238788273cf4d1676e0521140a98c0251b8 100644 (file)
@@ -20,10 +20,8 @@ lib_gtksheet_libgtksheet_a_SOURCES = \
        lib/gtksheet/gtkxpaned.h \
        lib/gtksheet/psppire-axis.c \
        lib/gtksheet/psppire-axis.h \
-       lib/gtksheet/psppire-axis-hetero.c \
-       lib/gtksheet/psppire-axis-hetero.h \
-       lib/gtksheet/psppire-axis-uniform.c \
-       lib/gtksheet/psppire-axis-uniform.h 
+       lib/gtksheet/psppire-axis-impl.c \
+       lib/gtksheet/psppire-axis-impl.h 
 
 
 EXTRA_DIST += lib/gtksheet/OChangeLog \
diff --git a/lib/gtksheet/psppire-axis-hetero.c b/lib/gtksheet/psppire-axis-hetero.c
deleted file mode 100644 (file)
index aad3da7..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* 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 <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <libpspp/tower.h>
-#include <libpspp/pool.h>
-#include "psppire-axis-hetero.h"
-#include <gtk/gtk.h>
-
-
-/* --- prototypes --- */
-static void psppire_axis_hetero_class_init (PsppireAxisHeteroClass     *class);
-static void psppire_axis_hetero_init   (PsppireAxisHetero              *axis);
-static void psppire_axis_hetero_finalize   (GObject            *object);
-
-
-/* --- variables --- */
-static GObjectClass     *parent_class = NULL;
-
-
-static gint
-get_unit_at_pixel (const PsppireAxis *a, glong pixel)
-{
-  PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
-  const struct tower_node *node;
-  unsigned long int node_start;
-
-  if (pixel >= tower_height (&ah->tower))
-    return tower_count (&ah->tower);
-
-  node = tower_lookup (&ah->tower, pixel, &node_start);
-
-  return tower_node_get_index (node);
-}
-
-
-static gint
-unit_count (const PsppireAxis *a)
-{
-  PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
-  return tower_count (&ah->tower);
-}
-
-
-static glong
-pixel_start (const PsppireAxis *a, gint unit)
-{
-  PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
-  const struct tower_node *node;
-
-  if ( unit >= tower_count (&ah->tower))
-    return tower_height (&ah->tower);
-
-  node = tower_get (&ah->tower, unit);
-
-  return  tower_node_get_level (node);
-}
-
-
-static gint
-unit_size (const PsppireAxis *a, gint unit)
-{
-  PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
-  const struct tower_node *node;
-  if  (unit >= tower_count (&ah->tower))
-    return 0;
-
-  node = tower_get (&ah->tower, unit);
-
-  return tower_node_get_size (node);
-}
-
-
-static glong
-total_size (const PsppireAxis *a)
-{
-  glong s;
-  PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
-
-  s =  tower_height (&ah->tower);
-  return s;
-}
-
-static void
-psppire_hetero_iface_init (PsppireAxisIface *iface)
-{
-  iface->unit_size = unit_size;
-  iface->unit_count = unit_count;
-  iface->pixel_start = pixel_start;
-  iface->get_unit_at_pixel = get_unit_at_pixel;
-  iface->total_size = total_size;
-}
-
-/* --- functions --- */
-/**
- * psppire_axis_hetero_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_axis_hetero_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      static const GTypeInfo object_info = {
-       sizeof (PsppireAxisHeteroClass),
-       (GBaseInitFunc) NULL,
-       (GBaseFinalizeFunc) NULL,
-       (GClassInitFunc) psppire_axis_hetero_class_init,
-       NULL,   /* class_finalize */
-       NULL,   /* class_data */
-       sizeof (PsppireAxisHetero),
-       0,      /* n_preallocs */
-       (GInstanceInitFunc) psppire_axis_hetero_init,
-      };
-
-
-      static const GInterfaceInfo interface_info =
-      {
-       (GInterfaceInitFunc) psppire_hetero_iface_init,
-       NULL,
-       NULL
-      };
-
-      object_type = g_type_register_static (G_TYPE_PSPPIRE_AXIS,
-                                           "PsppireAxisHetero",
-                                           &object_info, 0);
-
-      g_type_add_interface_static (object_type,
-                                  PSPPIRE_TYPE_AXIS_IFACE,
-                                  &interface_info);
-    }
-
-  return object_type;
-}
-
-static void
-psppire_axis_hetero_class_init (PsppireAxisHeteroClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-  parent_class = g_type_class_peek_parent (class);
-
-  object_class->finalize = psppire_axis_hetero_finalize;
-}
-
-
-static void
-psppire_axis_hetero_init (PsppireAxisHetero *axis)
-{
-  axis->pool = NULL;
-  psppire_axis_hetero_clear (axis);
-}
-
-
-static void
-psppire_axis_hetero_finalize (GObject *object)
-{
-  PsppireAxisHetero *a = PSPPIRE_AXIS_HETERO (object);
-  pool_destroy (a->pool);
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * psppire_axis_hetero_new:
- * @returns: a new #PsppireAxisHetero object
- *
- * Creates a new #PsppireAxisHetero.
- */
-PsppireAxisHetero*
-psppire_axis_hetero_new (void)
-{
-  return g_object_new (G_TYPE_PSPPIRE_AXIS_HETERO, NULL);
-}
-
-
-void
-psppire_axis_hetero_append (PsppireAxisHetero *a, gint size)
-{
-  struct tower_node *new ;
-
-  g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
-
-  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_hetero_insert (PsppireAxisHetero *a, gint size, gint posn)
-{
-  struct tower_node *new;
-  struct tower_node *before = NULL;
-
-  g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
-
-  new = pool_malloc (a->pool, sizeof *new);
-
-  if ( posn != tower_count (&a->tower))
-    before = tower_get (&a->tower, posn);
-
-  tower_insert (&a->tower, size, new, before);
-}
-
-
-void
-psppire_axis_hetero_remove (PsppireAxisHetero *a, gint posn)
-{
-  struct tower_node *node;
-
-  g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
-
-  node = tower_get (&a->tower, posn);
-
-  tower_delete (&a->tower, node);
-
-  pool_free (a->pool, node);
-}
-
-
-void
-psppire_axis_hetero_resize_unit (PsppireAxisHetero *a, gint size, gint posn)
-{
-  struct tower_node *node;
-
-  g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
-
-  node = tower_get (&a->tower, posn);
-
-  tower_resize (&a->tower, node, size);
-}
-
-
-void
-psppire_axis_hetero_clear (PsppireAxisHetero *a)
-{
-  g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
-
-  pool_destroy (a->pool);
-  a->pool = pool_create ();
-  tower_init (&a->tower);
-}
-
-
diff --git a/lib/gtksheet/psppire-axis-hetero.h b/lib/gtksheet/psppire-axis-hetero.h
deleted file mode 100644 (file)
index c1b674c..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* 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 <http://www.gnu.org/licenses/>. */
-
-
-#ifndef PSPPIRE_AXIS_HETERO_H__
-#define PSPPIRE_AXIS_HETERO_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include <libpspp/tower.h>
-#include "psppire-axis.h"
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_AXIS_HETERO              (psppire_axis_hetero_get_type ())
-#define PSPPIRE_AXIS_HETERO(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS_HETERO, PsppireAxisHetero))
-#define PSPPIRE_AXIS_HETERO_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS_HETERO, PsppireAxisHeteroClass))
-#define PSPPIRE_IS_AXIS_HETERO(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS_HETERO))
-#define PSPPIRE_IS_AXIS_HETERO_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS_HETERO))
-#define PSPPIRE_AXIS_HETERO_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS_HETERO, PsppireAxisHeteroClass))
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireAxisHetero         PsppireAxisHetero;
-typedef struct _PsppireAxisHeteroClass PsppireAxisHeteroClass;
-
-struct pool;
-
-struct _PsppireAxisHetero
-{
-  PsppireAxis  parent;
-
-  struct tower tower;
-  struct pool *pool;
-};
-
-struct _PsppireAxisHeteroClass
-{
-  PsppireAxisClass parent_class;
-};
-
-GType          psppire_axis_hetero_get_type (void);
-
-PsppireAxisHetero*   psppire_axis_hetero_new (void);
-
-\f
-/* Interface between axis and model */
-
-void psppire_axis_hetero_clear (PsppireAxisHetero *a);
-
-void psppire_axis_hetero_append (PsppireAxisHetero *a, gint size);
-
-void psppire_axis_hetero_insert (PsppireAxisHetero *a, gint size, gint posn);
-
-void psppire_axis_hetero_remove (PsppireAxisHetero *a, gint posn);
-
-void psppire_axis_hetero_resize_unit (PsppireAxisHetero *a, gint size, gint posn);
-
-
-G_END_DECLS
-
-#endif /* PSPPIRE_AXIS_HETERO_H__ */
diff --git a/lib/gtksheet/psppire-axis-impl.c b/lib/gtksheet/psppire-axis-impl.c
new file mode 100644 (file)
index 0000000..0505d1a
--- /dev/null
@@ -0,0 +1,383 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <libpspp/tower.h>
+#include <libpspp/pool.h>
+#include "psppire-axis-impl.h"
+#include <math.h>
+
+
+/* --- prototypes --- */
+static void psppire_axis_impl_class_init (PsppireAxisImplClass *class);
+static void psppire_axis_impl_init     (PsppireAxisImpl                *axis);
+static void psppire_axis_impl_finalize   (GObject              *object);
+
+
+/* --- variables --- */
+static GObjectClass     *parent_class = NULL;
+
+
+struct axis_node
+{
+  struct tower_node pixel_node;
+  struct tower_node unit_node;
+};
+
+static gint
+get_unit_at_pixel (const PsppireAxis *axis, glong pixel)
+{
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+
+  unsigned long int start;
+
+  struct tower_node *n = tower_lookup (&a->pixel_tower, pixel, &start);
+
+  struct axis_node *an = tower_data (n, struct axis_node, pixel_node);
+
+  gfloat fraction = (pixel - start) / (gfloat) tower_node_get_size (&an->pixel_node);
+
+  return  tower_node_get_level (&an->unit_node) + fraction * tower_node_get_size (&an->unit_node);
+}
+
+
+static gint
+unit_count (const PsppireAxis *axis)
+{
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+
+  return tower_height (&a->unit_tower);
+}
+
+
+/* Returns the pixel at the start of UNIT */
+static glong
+pixel_start (const PsppireAxis *axis, gint unit)
+{
+  gfloat fraction;
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+  struct tower_node *n ;
+  struct axis_node *an;
+
+  unsigned long int start;
+
+  if ( unit < 0)
+    return -1;
+
+  if ( unit >= unit_count (axis))
+    return -1;
+
+  n = tower_lookup (&a->unit_tower, unit, &start);
+
+  an = tower_data (n, struct axis_node, unit_node);
+
+  fraction = (unit - start) / (gfloat) tower_node_get_size (&an->unit_node);
+
+  return  tower_node_get_level (&an->pixel_node) +
+    nearbyintf (fraction * tower_node_get_size (&an->pixel_node));
+}
+
+
+static gint
+unit_size (const PsppireAxis *axis, gint unit)
+{
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+  struct tower_node *n ;
+  struct axis_node *an;
+
+  unsigned long int start;
+
+  if ( unit < 0)
+    return 0;
+
+  if ( unit >= unit_count (axis))
+    return 0;
+
+  n = tower_lookup (&a->unit_tower, unit, &start);
+
+  an = tower_data (n, struct axis_node, unit_node);
+
+  return nearbyintf (tower_node_get_size (&an->pixel_node)
+                    / (float) tower_node_get_size (&an->unit_node));
+}
+
+
+static glong
+total_size (const PsppireAxis *axis)
+{
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+
+  return tower_height (&a->pixel_tower);
+}
+
+
+
+
+static void
+psppire_impl_iface_init (PsppireAxisIface *iface)
+{
+  iface->unit_size = unit_size;
+  iface->unit_count = unit_count;
+  iface->pixel_start = pixel_start;
+  iface->get_unit_at_pixel = get_unit_at_pixel;
+  iface->total_size = total_size;
+}
+
+/* --- functions --- */
+/**
+ * psppire_axis_impl_get_type:
+ * @returns: the type ID for accelerator groups.
+ */
+GType
+psppire_axis_impl_get_type (void)
+{
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      static const GTypeInfo object_info = {
+       sizeof (PsppireAxisImplClass),
+       (GBaseInitFunc) NULL,
+       (GBaseFinalizeFunc) NULL,
+       (GClassInitFunc) psppire_axis_impl_class_init,
+       NULL,   /* class_finalize */
+       NULL,   /* class_data */
+       sizeof (PsppireAxisImpl),
+       0,      /* n_preallocs */
+       (GInstanceInitFunc) psppire_axis_impl_init,
+      };
+
+      static const GInterfaceInfo interface_info =
+      {
+       (GInterfaceInitFunc) psppire_impl_iface_init,
+       NULL,
+       NULL
+      };
+
+
+      object_type = g_type_register_static (G_TYPE_PSPPIRE_AXIS,
+                                           "PsppireAxisImpl",
+                                           &object_info, 0);
+
+
+      g_type_add_interface_static (object_type,
+                                  PSPPIRE_TYPE_AXIS_IFACE,
+                                  &interface_info);
+    }
+
+  return object_type;
+}
+
+static void
+psppire_axis_impl_class_init (PsppireAxisImplClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  parent_class = g_type_class_peek_parent (class);
+
+  object_class->finalize = psppire_axis_impl_finalize;
+}
+
+
+static void
+psppire_axis_impl_init (PsppireAxisImpl *axis)
+{
+  tower_init (&axis->pixel_tower);
+  tower_init (&axis->unit_tower);
+
+  axis->pool = pool_create ();
+}
+
+
+static void
+psppire_axis_impl_finalize (GObject *object)
+{
+  PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (object);
+  pool_destroy (a->pool);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * psppire_axis_impl_new:
+ * @returns: a new #PsppireAxisImpl object
+ *
+ * Creates a new #PsppireAxisImpl.
+ */
+PsppireAxisImpl*
+psppire_axis_impl_new (void)
+{
+  return g_object_new (G_TYPE_PSPPIRE_AXIS_IMPL, NULL);
+}
+
+
+\f
+
+void
+psppire_axis_impl_append (PsppireAxisImpl *a, gint size)
+{
+  psppire_axis_impl_append_n (a, 1, size);
+}
+
+
+void
+psppire_axis_impl_append_n (PsppireAxisImpl *a, gint n_units, gint size)
+{
+  struct axis_node *node = pool_alloc (a->pool, sizeof *node);
+
+
+  tower_insert (&a->unit_tower, n_units, &node->unit_node, NULL);
+  tower_insert (&a->pixel_tower, size * n_units, &node->pixel_node, NULL);
+}
+
+
+/* Split the node of both towers at POSN */
+static void
+split (PsppireAxisImpl *a, gint posn)
+{
+  unsigned long int existing_unit_size;
+  unsigned long int existing_pixel_size;
+  unsigned long int start;
+  gfloat fraction;
+  struct axis_node *new_node ;
+  struct tower_node *n = tower_lookup (&a->unit_tower, posn, &start);
+
+  struct axis_node *existing_node =
+    tower_data (n, struct axis_node, unit_node);
+
+  /* Nothing needs to be done, if the range element is already split here */
+  if ( posn - start == 0)
+    return;
+
+  existing_unit_size = tower_node_get_size (&existing_node->unit_node);
+  existing_pixel_size = tower_node_get_size (&existing_node->pixel_node);
+
+  fraction = (posn - start) / (gfloat) existing_unit_size;
+
+  new_node = pool_alloc (a->pool, sizeof (*new_node));
+
+  tower_resize (&a->unit_tower, &existing_node->unit_node, posn - start);
+
+  tower_resize (&a->pixel_tower, &existing_node->pixel_node,
+               nearbyintf (fraction * existing_pixel_size));
+
+  tower_insert (&a->unit_tower,
+               existing_unit_size - (posn - start),
+               &new_node->unit_node,
+               tower_next (&a->unit_tower, &existing_node->unit_node));
+
+
+  tower_insert (&a->pixel_tower,
+               nearbyintf (existing_pixel_size * (1 - fraction)),
+               &new_node->pixel_node,
+               tower_next (&a->pixel_tower, &existing_node->pixel_node));
+}
+
+
+/* Insert a new unit of size SIZE before POSN */
+void
+psppire_axis_impl_insert (PsppireAxisImpl *a, gint posn, gint size)
+{
+  struct tower_node *n;
+  unsigned long int start;
+  struct axis_node *before;
+  struct axis_node *new_node = pool_alloc (a->pool, sizeof (*new_node));
+
+  split (a, posn);
+
+  n = tower_lookup (&a->unit_tower, posn, &start);
+  g_assert (posn == start);
+
+  before = tower_data (n, struct axis_node, unit_node);
+
+  tower_insert (&a->unit_tower,
+               1,
+               &new_node->unit_node,
+               &before->unit_node);
+
+
+  tower_insert (&a->pixel_tower,
+               size,
+               &new_node->pixel_node,
+               &before->pixel_node);
+}
+
+
+/* Make the element at POSN singular.
+   Return a pointer to the node for this element */
+static struct axis_node *
+make_single (PsppireAxisImpl *a, gint posn)
+{
+  unsigned long int start;
+  struct tower_node *n;
+  n = tower_lookup (&a->unit_tower, posn, &start);
+
+  if ( 1 != tower_node_get_size (n))
+    {
+      split (a, posn + 1);
+      n = tower_lookup (&a->unit_tower, posn, &start);
+
+      if ( 1 != tower_node_get_size (n))
+       {
+         split (a, posn);
+         n = tower_lookup (&a->unit_tower, posn, &start);
+       }
+    }
+
+  g_assert (1 == tower_node_get_size (n));
+
+
+  return tower_data (n, struct axis_node, unit_node);
+}
+
+void
+psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size)
+{
+  struct axis_node *an =  make_single (a, posn);
+
+  tower_resize (&a->pixel_tower, &an->pixel_node, size);
+}
+
+
+
+void
+psppire_axis_impl_clear (PsppireAxisImpl *a)
+{
+  pool_destroy (a->pool);
+  a->pool = pool_create ();
+
+  tower_init (&a->pixel_tower);
+  tower_init (&a->unit_tower);
+}
+
+
+
+void
+psppire_axis_impl_delete (PsppireAxisImpl *a, gint first, gint n_cases)
+{
+  gint i;
+  g_warning ("%s FIXME: This is an inefficient implementation", __FUNCTION__);
+
+  for (i = first; i < first + n_cases; ++i)
+    {
+      struct axis_node *an = make_single (a, i);
+
+      tower_delete (&a->unit_tower, &an->unit_node);
+      tower_delete (&a->pixel_tower, &an->pixel_node);
+    }
+}
diff --git a/lib/gtksheet/psppire-axis-impl.h b/lib/gtksheet/psppire-axis-impl.h
new file mode 100644 (file)
index 0000000..84193ae
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+
+#ifndef PSPPIRE_AXIS_IMPL_H__
+#define PSPPIRE_AXIS_IMPL_H__
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-axis.h"
+#include <libpspp/tower.h>
+
+G_BEGIN_DECLS
+
+
+/* --- type macros --- */
+#define G_TYPE_PSPPIRE_AXIS_IMPL              (psppire_axis_impl_get_type ())
+#define PSPPIRE_AXIS_IMPL(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImpl))
+#define PSPPIRE_AXIS_IMPL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImplClass))
+#define PSPPIRE_IS_AXIS_IMPL(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS_IMPL))
+#define PSPPIRE_IS_AXIS_IMPL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS_IMPL))
+#define PSPPIRE_AXIS_IMPL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImplClass))
+
+
+
+/* --- typedefs & structures --- */
+typedef struct _PsppireAxisImpl           PsppireAxisImpl;
+typedef struct _PsppireAxisImplClass PsppireAxisImplClass;
+
+struct pool;
+
+struct _PsppireAxisImpl
+{
+  PsppireAxis  parent;
+
+  struct tower pixel_tower;
+  struct tower unit_tower;
+
+  struct pool *pool;
+};
+
+struct _PsppireAxisImplClass
+{
+  PsppireAxisClass parent_class;
+};
+
+GType          psppire_axis_impl_get_type (void);
+
+PsppireAxisImpl*   psppire_axis_impl_new (void);
+
+\f
+/* Interface between axis and model */
+
+
+
+void psppire_axis_impl_insert (PsppireAxisImpl *a, gint posn, gint size);
+
+void psppire_axis_impl_append (PsppireAxisImpl *a, gint size);
+
+
+void psppire_axis_impl_append_n (PsppireAxisImpl *a, gint n_units, gint size);
+
+void psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size);
+
+void psppire_axis_impl_clear (PsppireAxisImpl *);
+
+
+void psppire_axis_impl_delete (PsppireAxisImpl *, gint first, gint n_cases);
+
+
+
+G_END_DECLS
+
+#endif /* PSPPIRE_AXIS_IMPL_H__ */
diff --git a/lib/gtksheet/psppire-axis-uniform.c b/lib/gtksheet/psppire-axis-uniform.c
deleted file mode 100644 (file)
index 8763da1..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/* 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 <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <libpspp/tower.h>
-#include <libpspp/pool.h>
-#include "psppire-axis-uniform.h"
-#include <gtk/gtk.h>
-
-
-/* --- prototypes --- */
-static void psppire_axis_uniform_class_init (PsppireAxisUniformClass   *class);
-static void psppire_axis_uniform_init  (PsppireAxisUniform             *axis);
-static void psppire_axis_uniform_finalize   (GObject           *object);
-
-
-/* --- variables --- */
-static GObjectClass     *parent_class = NULL;
-
-
-#define UNIT_SIZE 25
-
-static gint
-get_unit_at_pixel (const PsppireAxis *a, glong pixel)
-{
-  gint unit_size;
-  PsppireAxisUniform *au = PSPPIRE_AXIS_UNIFORM (a);
-
-  g_object_get (au, "default-size", &unit_size, NULL);
-
-  return pixel / unit_size;
-}
-
-
-static gint
-unit_count (const PsppireAxis *a)
-{
-  PsppireAxisUniform *au = PSPPIRE_AXIS_UNIFORM (a);
-
-  return au->n_items;
-}
-
-
-static glong
-pixel_start (const PsppireAxis *a, gint unit)
-{
-  gint unit_size;
-  PsppireAxisUniform *au = PSPPIRE_AXIS_UNIFORM (a);
-
-  g_object_get (au, "default-size", &unit_size, NULL);
-
-  return unit * unit_size;
-}
-
-
-static gint
-unit_size (const PsppireAxis *a, gint unit)
-{
-  gint unit_size;
-  PsppireAxisUniform *au = PSPPIRE_AXIS_UNIFORM (a);
-
-  g_object_get (au, "default-size", &unit_size, NULL);
-
-  return unit_size;
-}
-
-
-static glong
-total_size (const PsppireAxis *a)
-{
-  gint unit_size;
-  PsppireAxisUniform *au = PSPPIRE_AXIS_UNIFORM (a);
-
-  g_object_get (au, "default-size", &unit_size, NULL);
-
-  return unit_size * au->n_items;
-}
-
-
-
-static void
-psppire_uniform_iface_init (PsppireAxisIface *iface)
-{
-  iface->unit_size = unit_size;
-  iface->unit_count = unit_count;
-  iface->pixel_start = pixel_start;
-  iface->get_unit_at_pixel = get_unit_at_pixel;
-  iface->total_size = total_size;
-}
-
-/* --- functions --- */
-/**
- * psppire_axis_uniform_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_axis_uniform_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      static const GTypeInfo object_info = {
-       sizeof (PsppireAxisUniformClass),
-       (GBaseInitFunc) NULL,
-       (GBaseFinalizeFunc) NULL,
-       (GClassInitFunc) psppire_axis_uniform_class_init,
-       NULL,   /* class_finalize */
-       NULL,   /* class_data */
-       sizeof (PsppireAxisUniform),
-       0,      /* n_preallocs */
-       (GInstanceInitFunc) psppire_axis_uniform_init,
-      };
-
-      static const GInterfaceInfo interface_info =
-      {
-       (GInterfaceInitFunc) psppire_uniform_iface_init,
-       NULL,
-       NULL
-      };
-
-
-      object_type = g_type_register_static (G_TYPE_PSPPIRE_AXIS,
-                                           "PsppireAxisUniform",
-                                           &object_info, 0);
-
-
-      g_type_add_interface_static (object_type,
-                                  PSPPIRE_TYPE_AXIS_IFACE,
-                                  &interface_info);
-    }
-
-  return object_type;
-}
-
-static void
-psppire_axis_uniform_class_init (PsppireAxisUniformClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-  parent_class = g_type_class_peek_parent (class);
-
-  object_class->finalize = psppire_axis_uniform_finalize;
-}
-
-
-static void
-psppire_axis_uniform_init (PsppireAxisUniform *axis)
-{
-  axis->n_items = 0;
-}
-
-
-static void
-psppire_axis_uniform_finalize (GObject *object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * psppire_axis_uniform_new:
- * @returns: a new #PsppireAxisUniform object
- *
- * Creates a new #PsppireAxisUniform.
- */
-PsppireAxisUniform*
-psppire_axis_uniform_new (void)
-{
-  return g_object_new (G_TYPE_PSPPIRE_AXIS_UNIFORM, NULL);
-}
-
-
-
-\f
-
-
-void
-psppire_axis_uniform_set_count (PsppireAxisUniform *axis, gint n)
-{
-  axis->n_items = n;
-}
diff --git a/lib/gtksheet/psppire-axis-uniform.h b/lib/gtksheet/psppire-axis-uniform.h
deleted file mode 100644 (file)
index 49f434d..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* 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 <http://www.gnu.org/licenses/>. */
-
-
-#ifndef PSPPIRE_AXIS_UNIFORM_H__
-#define PSPPIRE_AXIS_UNIFORM_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include "psppire-axis.h"
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_AXIS_UNIFORM              (psppire_axis_uniform_get_type ())
-#define PSPPIRE_AXIS_UNIFORM(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS_UNIFORM, PsppireAxisUniform))
-#define PSPPIRE_AXIS_UNIFORM_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS_UNIFORM, PsppireAxisUniformClass))
-#define PSPPIRE_IS_AXIS_UNIFORM(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS_UNIFORM))
-#define PSPPIRE_IS_AXIS_UNIFORM_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS_UNIFORM))
-#define PSPPIRE_AXIS_UNIFORM_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS_UNIFORM, PsppireAxisUniformClass))
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireAxisUniform        PsppireAxisUniform;
-typedef struct _PsppireAxisUniformClass PsppireAxisUniformClass;
-
-struct pool;
-
-struct _PsppireAxisUniform
-{
-  PsppireAxis  parent;
-
-  gint n_items;
-};
-
-struct _PsppireAxisUniformClass
-{
-  PsppireAxisClass parent_class;
-};
-
-GType          psppire_axis_uniform_get_type (void);
-
-PsppireAxisUniform*   psppire_axis_uniform_new (void);
-
-\f
-/* Interface between axis and model */
-
-
-void psppire_axis_uniform_set_count (PsppireAxisUniform *axis, gint n);
-
-
-
-G_END_DECLS
-
-#endif /* PSPPIRE_AXIS_UNIFORM_H__ */
index 4ec23137967b9d442cdb1bd7b30d81542cc1b2bc..2d306fbc31d6bdffca674ea7abab5a57b113095c 100644 (file)
@@ -22,8 +22,6 @@
 #include <glib-object.h>
 #include <glib.h>
 
-#include <libpspp/tower.h>
-
 G_BEGIN_DECLS
 
 
index b6f66403116d249b66b29d2f879affc7d169dc28..674af4ec4db8efe6c76488dbf2534e5e7f946f80 100644 (file)
@@ -23,8 +23,7 @@
 
 #include <language/syntax-string-source.h>
 #include "psppire-data-store.h"
-#include <gtksheet/psppire-axis-hetero.h>
-#include <gtksheet/psppire-axis-uniform.h>
+#include <gtksheet/psppire-axis-impl.h>
 #include "helper.h"
 
 #include <gtksheet/gtkxpaned.h>
@@ -218,12 +217,13 @@ new_data_callback (PsppireDataStore *ds, gpointer data)
   gint i;
   for (i = 0 ; i < 4 ; ++i)
     {
-      PsppireAxisUniform *vaxis;
+      PsppireAxisImpl *vaxis;
       casenumber n_cases =  psppire_data_store_get_case_count (ds);
 
       g_object_get (de->data_sheet[i], "vertical-axis", &vaxis, NULL);
 
-      psppire_axis_uniform_set_count (vaxis, n_cases);
+      psppire_axis_impl_clear (vaxis);
+      psppire_axis_impl_append_n (vaxis, n_cases, DEFAULT_ROW_HEIGHT);
     }
 }
 
@@ -236,12 +236,11 @@ case_inserted_callback (PsppireDataStore *ds, gint before, gpointer data)
 
   for (i = 0 ; i < 4 ; ++i)
     {
-      PsppireAxisUniform *vaxis;
-      casenumber n_cases =  psppire_data_store_get_case_count (ds);
+      PsppireAxisImpl *vaxis;
 
       g_object_get (de->data_sheet[i], "vertical-axis", &vaxis, NULL);
 
-      psppire_axis_uniform_set_count (vaxis, n_cases + 1);
+      psppire_axis_impl_insert (vaxis, before, DEFAULT_ROW_HEIGHT);
     }
 }
 
@@ -255,12 +254,11 @@ cases_deleted_callback (PsppireDataStore *ds, gint first, gint n_cases, gpointer
 
   for (i = 0 ; i < 4 ; ++i)
     {
-      PsppireAxisUniform *vaxis;
-      casenumber case_count =  psppire_data_store_get_case_count (ds);
+      PsppireAxisImpl *vaxis;
 
       g_object_get (de->data_sheet[i], "vertical-axis", &vaxis, NULL);
 
-      psppire_axis_uniform_set_count (vaxis, case_count - n_cases);
+      psppire_axis_impl_delete (vaxis, first, n_cases);
     }
 }
 
@@ -289,28 +287,24 @@ new_variables_callback (PsppireDict *dict, gpointer data)
   PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
   gint m_width = width_of_m (GTK_WIDGET (de));
 
-  PsppireAxisHetero *vaxis;
+  PsppireAxisImpl *vaxis;
   g_object_get (de->var_sheet, "vertical-axis", &vaxis, NULL);
 
-  psppire_axis_hetero_clear (vaxis);
-
-  /* NOTE: "<=" in the following line is correct.
-     There needs to be one more row than there are variables */
-  for (v = 0 ; v <= psppire_dict_get_var_cnt (dict); ++v)
-    psppire_axis_hetero_append (vaxis, DEFAULT_ROW_HEIGHT);
+  psppire_axis_impl_clear (vaxis);
+  psppire_axis_impl_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
 
   for (i = 0 ; i < 4 ; ++i)
     {
-      PsppireAxisHetero *haxis;
+      PsppireAxisImpl *haxis;
       g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
 
-      psppire_axis_hetero_clear (haxis);
+      psppire_axis_impl_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_hetero_append (haxis, m_width * var_get_display_width (var));
+         psppire_axis_impl_append (haxis, m_width * var_get_display_width (var));
        }
     }
 }
@@ -324,18 +318,18 @@ insert_variable_callback (PsppireDict *dict, gint x, gpointer data)
 
   gint m_width  = width_of_m (GTK_WIDGET (de));
 
-  PsppireAxisHetero *var_vaxis;
+  PsppireAxisImpl *var_vaxis;
   g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
 
-  psppire_axis_hetero_insert (var_vaxis, DEFAULT_ROW_HEIGHT, x);
+  psppire_axis_impl_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
 
   for (i = 0 ; i < 4 ; ++i)
     {
       const struct variable *var = psppire_dict_get_variable (dict, x);
-      PsppireAxisHetero *haxis;
+      PsppireAxisImpl *haxis;
       g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
 
-      psppire_axis_hetero_insert (haxis, m_width * var_get_display_width (var), x);
+      psppire_axis_impl_insert (haxis, x, m_width * var_get_display_width (var));
     }
 }
 
@@ -347,17 +341,17 @@ delete_variable_callback (PsppireDict *dict, gint posn,
   gint i;
   PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
 
-  PsppireAxisHetero *var_vaxis;
+  PsppireAxisImpl *var_vaxis;
   g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
 
-  psppire_axis_hetero_remove (var_vaxis, posn);
+  psppire_axis_impl_delete (var_vaxis, posn, 1);
 
   for (i = 0 ; i < 4 ; ++i)
     {
-      PsppireAxisHetero *haxis;
+      PsppireAxisImpl *haxis;
       g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
 
-      psppire_axis_hetero_remove (haxis, posn);
+      psppire_axis_impl_delete (haxis, posn, 1);
     }
 }
 
@@ -372,12 +366,11 @@ rewidth_variable_callback (PsppireDict *dict, gint posn, gpointer data)
   for (i = 0 ; i < 4 ; ++i)
     {
       const struct variable *var = psppire_dict_get_variable (dict, posn);
-      PsppireAxisHetero *haxis;
+      PsppireAxisImpl *haxis;
       g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
 
-      psppire_axis_hetero_resize_unit (haxis,
-                                      m_width *
-                                      var_get_display_width (var), posn);
+      psppire_axis_impl_resize (haxis, posn, m_width *
+                                 var_get_display_width (var));
     }
 }
 
@@ -837,8 +830,8 @@ static void
 init_sheet (PsppireDataEditor *de, int i,
            GtkAdjustment *hadj, GtkAdjustment *vadj)
 {
-  PsppireAxisHetero *haxis = psppire_axis_hetero_new ();
-  PsppireAxisUniform *vaxis = psppire_axis_uniform_new ();
+  PsppireAxisImpl *haxis = psppire_axis_impl_new ();
+  PsppireAxisImpl *vaxis = psppire_axis_impl_new ();
   de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj);
 
   de->data_sheet[i] = gtk_sheet_new (NULL);
index c17301056586ac8ad6c844e2a64face30e0ab44f..615dd6520f4e17fce5b215bf89ed07266e49ebc2 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <config.h>
 #include "psppire-var-sheet.h"
-#include <gtksheet/psppire-axis-hetero.h>
+#include <gtksheet/psppire-axis-impl.h>
 
 #include <glade/glade.h>
 #include "helper.h"
@@ -523,14 +523,13 @@ GtkWidget*
 psppire_var_sheet_new (void)
 {
   gint i;
-  PsppireAxisHetero *ha = psppire_axis_hetero_new ();
-  PsppireAxisHetero *va = psppire_axis_hetero_new ();
+  PsppireAxisImpl *ha = psppire_axis_impl_new ();
+  PsppireAxisImpl *va = psppire_axis_impl_new ();
 
   GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL);
 
   for (i = 0 ; i < 10 ; ++i)
-    psppire_axis_hetero_append (ha, column_def[i].width);
-
+    psppire_axis_impl_append (ha, column_def[i].width);
 
   g_object_set (va,
                "default-size", 25,