lib_gtksheet_libgtksheet_a_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
lib_gtksheet_libgtksheet_a_SOURCES = \
- lib/gtksheet/psppire-sheetmodel.c \
- lib/gtksheet/psppire-sheetmodel.h \
lib/gtksheet/gtkextra-sheet.h \
lib/gtksheet/psppire-sheet.c \
lib/gtksheet/psppire-sheet.h \
lib/gtksheet/gtkxpaned.c \
- lib/gtksheet/gtkxpaned.h \
- lib/gtksheet/psppire-axis.c \
- lib/gtksheet/psppire-axis.h \
- lib/gtksheet/psppire-axis-impl.c \
- lib/gtksheet/psppire-axis-impl.h
-
+ lib/gtksheet/gtkxpaned.h
EXTRA_DIST += lib/gtksheet/OChangeLog \
lib/gtksheet/README
+++ /dev/null
-/* 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;
-};
-
-void
-psppire_axis_impl_dump (const PsppireAxisImpl *a)
-{
- struct tower_node *n = tower_first (&a->unit_tower);
-
- g_debug ("Axis %p", a);
- while (n)
- {
- const struct axis_node *an = tower_data (n, struct axis_node, unit_node);
- const struct tower_node *pn = &an->pixel_node;
- g_debug ("%ld units of height %g",
- n->size, pn->size / (float) n->size);
-
- n = tower_next (&a->unit_tower, n);
- }
- g_debug ("\n");
-}
-
-static gint
-unit_at_pixel (const PsppireAxis *axis, glong pixel)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
-
- unsigned long int start;
- struct tower_node *n;
- struct axis_node *an;
- gfloat fraction;
-
- g_return_val_if_fail (pixel >= 0, -1);
-
- n = tower_lookup (&a->pixel_tower, pixel, &start);
- an = tower_data (n, struct axis_node, pixel_node);
-
- 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
-start_pixel (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 resize (PsppireAxis *axis, gint posn, glong size);
-
-
-
-static void
-psppire_impl_iface_init (PsppireAxisIface *iface)
-{
- iface->unit_size = unit_size;
- iface->unit_count = unit_count;
- iface->start_pixel = start_pixel;
- iface->unit_at_pixel = unit_at_pixel;
- iface->total_size = total_size;
- iface->resize = resize;
-}
-
-/* --- 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;
-
- if (n_units == 0)
- return;
-
- node = pool_malloc (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;
- struct axis_node *existing_node;
-
- g_return_if_fail (posn <= tower_height (&a->unit_tower));
-
- /* Nothing needs to be done */
- if ( posn == 0 || posn == tower_height (&a->unit_tower))
- return;
-
- n = tower_lookup (&a->unit_tower, posn, &start);
-
- 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_malloc (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 axis_node *before = NULL;
- struct axis_node *new_node;
-
- g_return_if_fail ( posn >= 0);
- g_return_if_fail ( posn <= tower_height (&a->unit_tower));
-
- if ( posn < tower_height (&a->unit_tower))
- {
- unsigned long int start = 0;
- struct tower_node *n;
-
- split (a, posn);
-
- n = tower_lookup (&a->unit_tower, posn, &start);
- g_assert (posn == start);
-
- before = tower_data (n, struct axis_node, unit_node);
- }
-
- new_node = pool_malloc (a->pool, sizeof (*new_node));
-
- tower_insert (&a->unit_tower,
- 1,
- &new_node->unit_node,
- before ? &before->unit_node : NULL);
-
- tower_insert (&a->pixel_tower,
- size,
- &new_node->pixel_node,
- before ? &before->pixel_node : NULL);
-}
-
-
-/* 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;
-
- g_return_val_if_fail (posn < tower_height (&a->unit_tower), NULL);
-
- 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);
-}
-
-
-static void
-resize (PsppireAxis *axis, gint posn, glong size)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
-
- struct axis_node *an;
- g_return_if_fail (posn >= 0);
- g_return_if_fail (size > 0);
-
- /* Silently ignore this request if the position is greater than the number of
- units in the axis */
- if (posn >= tower_height (&a->unit_tower))
- return ;
-
- an = make_single (a, posn);
-
- tower_resize (&a->pixel_tower, &an->pixel_node, size);
-}
-
-
-void
-psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size)
-{
- resize (PSPPIRE_AXIS (a), posn, 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_units)
-{
- gint units_to_delete = n_units;
- unsigned long int start;
- struct tower_node *unit_node ;
- g_return_if_fail (first + n_units <= tower_height (&a->unit_tower));
-
- split (a, first);
- split (a, first + n_units);
-
- unit_node = tower_lookup (&a->unit_tower, first, &start);
- g_assert (start == first);
-
- while (units_to_delete > 0)
- {
- struct tower_node *next_unit_node;
- struct axis_node *an = tower_data (unit_node,
- struct axis_node, unit_node);
-
- g_assert (unit_node == &an->unit_node);
- g_assert (unit_node->size <= n_units);
-
- units_to_delete -= unit_node->size;
-
- next_unit_node = tower_next (&a->unit_tower, unit_node);
-
- tower_delete (&a->unit_tower, unit_node);
- tower_delete (&a->pixel_tower, &an->pixel_node);
-
- pool_free (a->pool, an);
-
- unit_node = next_unit_node;
- }
-}
+++ /dev/null
-/* 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__ */
+++ /dev/null
-/* 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 <libpspp/misc.h>
-#include "psppire-axis.h"
-#include <ui/gui/psppire-marshal.h>
-#include <gtk/gtk.h>
-
-
-
-/* Signals */
-enum
- {
- RESIZE_UNIT,
- n_signals
- };
-
-static guint signals[n_signals] ;
-
-
-#define PSPPIRE_AXIS_GET_IFACE(obj) \
- (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_AXIS_IFACE, PsppireAxisIface))
-
-GType
-psppire_axis_iface_get_type (void)
-{
- static GType psppire_axis_iface_type = 0;
-
- if (! psppire_axis_iface_type)
- {
- static const GTypeInfo psppire_axis_iface_info =
- {
- sizeof (PsppireAxisIface), /* class_size */
- NULL, /* base init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- psppire_axis_iface_type =
- g_type_register_static (G_TYPE_INTERFACE, "PsppireAxisIface",
- &psppire_axis_iface_info, 0);
- }
-
- return psppire_axis_iface_type;
-}
-
-G_DEFINE_ABSTRACT_TYPE(PsppireAxis, psppire_axis, G_TYPE_OBJECT);
-
-
-
-/* --- 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;
-
-
-
-enum
- {
- PROP_0,
- PROP_MIN_EXTENT,
- PROP_DEFAULT_SIZE
- };
-
-
-static void
-psppire_axis_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- PsppireAxis *axis = PSPPIRE_AXIS (object);
-
- switch (prop_id)
- {
- case PROP_MIN_EXTENT:
- g_value_set_long (value, axis->min_extent);
- break;
- case PROP_DEFAULT_SIZE:
- g_value_set_int (value, axis->default_size);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- };
-}
-
-
-static void
-psppire_axis_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- PsppireAxis *axis = PSPPIRE_AXIS (object);
-
- switch (prop_id)
- {
- case PROP_MIN_EXTENT:
- axis->min_extent = g_value_get_long (value);
- break;
- case PROP_DEFAULT_SIZE:
- axis->default_size = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- };
-}
-
-static void
-psppire_axis_class_init (PsppireAxisClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GParamSpec *min_extent_spec;
- GParamSpec *default_size_spec;
-
- object_class->set_property = psppire_axis_set_property;
- object_class->get_property = psppire_axis_get_property;
-
- min_extent_spec =
- g_param_spec_long ("minimum-extent",
- "Minimum Extent",
- "The smallest extent to which the axis will provide units (typically set to the height/width of the associated widget).",
- 0, G_MAXLONG,
- 0,
- G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE );
-
- g_object_class_install_property (object_class,
- PROP_MIN_EXTENT,
- min_extent_spec);
-
-
- default_size_spec =
- g_param_spec_int ("default-size",
- "Default Size",
- "The size given to units which haven't been explicity inserted",
- 0, G_MAXINT,
- 25,
- G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE );
-
-
- g_object_class_install_property (object_class,
- PROP_DEFAULT_SIZE,
- default_size_spec);
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class->finalize = psppire_axis_finalize;
-
-
- signals[RESIZE_UNIT] =
- g_signal_new ("resize-unit",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- psppire_marshal_VOID__INT_LONG,
- G_TYPE_NONE,
- 2,
- G_TYPE_INT,
- G_TYPE_LONG
- );
-}
-
-
-static void
-psppire_axis_init (PsppireAxis *axis)
-{
-}
-
-
-static void
-psppire_axis_finalize (GObject *object)
-{
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-gint
-psppire_axis_unit_size (const PsppireAxis *a, gint unit)
-{
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
-
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_size, -1);
-
-
- if (unit >= PSPPIRE_AXIS_GET_IFACE (a)->unit_count(a))
- return a->default_size;
-
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_size (a, unit);
-}
-
-gint
-psppire_axis_unit_count (const PsppireAxis *a)
-{
- glong padding = 0;
- glong actual_size;
-
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_count, -1);
-
- actual_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
-
- if ( actual_size < a->min_extent )
- padding = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
-
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a) + padding;
-}
-
-
-/* Return the starting pixel of UNIT */
-glong
-psppire_axis_start_pixel (const PsppireAxis *a, gint unit)
-{
- gint the_count, total_size ;
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
-
- the_count = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
- total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
-
- if ( unit >= the_count)
- {
- return total_size + (unit - the_count) * a->default_size;
- }
-
- return PSPPIRE_AXIS_GET_IFACE (a)->start_pixel (a, unit);
-}
-
-
-/* Return the unit covered by PIXEL */
-gint
-psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
-{
- glong total_size;
-
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
-
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a), -1);
-
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel, -1);
-
- total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
-
- if (pixel >= total_size)
- {
- gint n_items = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
- glong extra = pixel - total_size;
-
- return n_items - 1 + DIV_RND_UP (extra, a->default_size);
- }
-
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel (a, pixel);
-}
-
-
-/* Set UNIT to size SIZE */
-void
-psppire_axis_resize (PsppireAxis *a, gint unit, glong size)
-{
- g_return_if_fail (PSPPIRE_IS_AXIS (a));
-
- g_return_if_fail (PSPPIRE_AXIS_GET_IFACE (a));
-
- g_return_if_fail (size > 0);
-
- if (PSPPIRE_AXIS_GET_IFACE (a)->resize)
- PSPPIRE_AXIS_GET_IFACE (a)->resize (a, unit, size);
-
-
- g_signal_emit (a, signals [RESIZE_UNIT], 0, unit, size);
-}
-
-
+++ /dev/null
-/* 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_H__
-#define PSPPIRE_AXIS_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-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 _PsppireAxis
-{
- GObject parent;
-
- glong min_extent;
- gint default_size;
-};
-
-struct _PsppireAxisClass
-{
- GObjectClass parent_class;
-};
-
-
-GType psppire_axis_get_type (void);
-
-
-\f
-
-GType psppire_axis_iface_get_type (void);
-
-#define PSPPIRE_TYPE_AXIS_IFACE (psppire_axis_iface_get_type ())
-
-typedef struct _PsppireAxisIface PsppireAxisIface;
-
-struct _PsppireAxisIface
-{
- GTypeInterface g_iface;
-
-
- /* Virtual Table */
-
- gint (*unit_size) (const PsppireAxis *a, gint unit);
-
- gint (*unit_count) (const PsppireAxis *a);
-
- glong (*start_pixel) (const PsppireAxis *a, gint unit);
-
- gint (*unit_at_pixel) (const PsppireAxis *a, glong pixel);
-
- glong (*total_size) (const PsppireAxis *a);
-
-
- void (*resize) (PsppireAxis *a, gint unit, glong pixels);
-};
-
-
-/* Interface between sheet and axis */
-
-gint psppire_axis_unit_size (const PsppireAxis *a, gint unit);
-
-gint psppire_axis_unit_count (const PsppireAxis *a);
-
-glong psppire_axis_start_pixel (const PsppireAxis *a, gint unit);
-
-gint psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel);
-
-
-void psppire_axis_resize (PsppireAxis *a, gint unit, glong size);
-
-G_END_DECLS
-
-#endif /* PSPPIRE_AXIS_H__ */
#include <pango/pango.h>
#include "psppire-sheet.h"
#include <ui/gui/psppire-marshal.h>
-#include "psppire-sheetmodel.h"
+#include <ui/gui/sheet/psppire-sheetmodel.h>
#include <libpspp/misc.h>
#include <math.h>
#include <gtk/gtk.h>
#include "gtkextra-sheet.h"
-#include "psppire-sheetmodel.h"
-#include "psppire-axis.h"
+#include <ui/gui/sheet/psppire-sheetmodel.h>
+#include <ui/gui/sheet/psppire-axis.h>
G_BEGIN_DECLS
+++ /dev/null
-/* PsppireSheetModel --- an abstract model for the PsppireSheet widget.
- * 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
- 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 <glib.h>
-#include "psppire-sheetmodel.h"
-#include <ui/gui/psppire-marshal.h>
-
-enum {
- RANGE_CHANGED,
- ROWS_INSERTED,
- ROWS_DELETED,
- COLUMNS_INSERTED,
- COLUMNS_DELETED,
- LAST_SIGNAL
-};
-
-static guint sheet_model_signals[LAST_SIGNAL] = { 0 };
-
-
-static void psppire_sheet_model_base_init (gpointer g_class);
-
-
-GType
-psppire_sheet_model_get_type (void)
-{
- static GType sheet_model_type = 0;
-
- if (! sheet_model_type)
- {
- static const GTypeInfo sheet_model_info =
- {
- sizeof (PsppireSheetModelIface), /* class_size */
- psppire_sheet_model_base_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- sheet_model_type =
- g_type_register_static (G_TYPE_INTERFACE, "PsppireSheetModel",
- &sheet_model_info, 0);
-
- g_type_interface_add_prerequisite (sheet_model_type, G_TYPE_OBJECT);
- }
-
- return sheet_model_type;
-}
-
-static void
-psppire_sheet_model_base_init (gpointer g_class)
-{
- static gboolean initialized = FALSE;
-
- if (! initialized)
- {
- sheet_model_signals[RANGE_CHANGED] =
- g_signal_new ("range_changed",
- PSPPIRE_TYPE_SHEET_MODEL,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PsppireSheetModelIface, range_changed),
- NULL, NULL,
- psppire_marshal_VOID__INT_INT_INT_INT,
- G_TYPE_NONE, 4,
- G_TYPE_INT,
- G_TYPE_INT,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
-
- sheet_model_signals[ROWS_INSERTED] =
- g_signal_new ("rows_inserted",
- PSPPIRE_TYPE_SHEET_MODEL,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PsppireSheetModelIface, rows_inserted),
- NULL, NULL,
- psppire_marshal_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
- sheet_model_signals[ROWS_DELETED] =
- g_signal_new ("rows_deleted",
- PSPPIRE_TYPE_SHEET_MODEL,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PsppireSheetModelIface, rows_deleted),
- NULL, NULL,
- psppire_marshal_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
- sheet_model_signals[COLUMNS_INSERTED] =
- g_signal_new ("columns_inserted",
- PSPPIRE_TYPE_SHEET_MODEL,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PsppireSheetModelIface, columns_inserted),
- NULL, NULL,
- psppire_marshal_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
- sheet_model_signals[COLUMNS_DELETED] =
- g_signal_new ("columns_deleted",
- PSPPIRE_TYPE_SHEET_MODEL,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PsppireSheetModelIface, columns_deleted),
- NULL, NULL,
- psppire_marshal_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
- initialized = TRUE;
- }
-}
-
-
-/**
- * psppire_sheet_model_free_strings
- * @sheet_model: A #PsppireSheetModel
- *
- * Returns: True if strings obtained with get_string should be freed by the
- * sheet when no longer required.
- **/
-gboolean
-psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->free_strings;
-}
-
-
-/**
- * psppire_sheet_model_get_string:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row of the cell to be retrieved.
- * @column: The column of the cell to be retrieved.
- *
- * Retrieves the datum at location ROW, COLUMN in the form of a string.
- * Returns: The string representation of the datum, or NULL on error.
- **/
-gchar *
-psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), 0);
-
- g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string);
-
- return (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string) (sheet_model, row, column);
-}
-
-/**
- * psppire_sheet_model_set_string
- * @sheet_model: A #PsppireSheetModel
- * @text: The text describing the datum to be set.
- * @row: The row of the cell to be cleared.
- * @column: The column of the cell to be cleared.
- *
- * Sets the datum at a location from a string.
- * Returns: TRUE if the datum was changed, FALSE otherwise.
- **/
-gboolean
-psppire_sheet_model_set_string (PsppireSheetModel *sheet_model,
- const gchar *text,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
-
- g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string);
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string (sheet_model,
- text, row, column);
-}
-
-
-
-/**
- * psppire_sheet_model_datum_clear:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row of the cell to be cleared.
- * @column: The column of the cell to be cleared.
- *
- * Called when the datum at a location is to be cleared.
- * Returns: TRUE if the datum was cleared, FALSE otherwise.
- **/
-gboolean
-psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
-
- g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum);
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum (sheet_model,
- row, column);
-}
-
-
-/**
- * psppire_sheet_model_range_changed:
- * @sheet_model: A #PsppireSheetModel
- * @range: The #PsppireSheetRange range of cells which have changed.
- *
- * Emits the "range_changed" signal on @sheet_model.
- **/
-void
-psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model,
- glong row0, glong col0,
- glong rowi, glong coli)
-{
- g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
-
- g_signal_emit (sheet_model, sheet_model_signals[RANGE_CHANGED], 0,
- row0, col0, rowi, coli);
-}
-
-
-
-
-/**
- * psppire_sheet_model_rows_inserted:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row before which the new rows should be inserted.
- * @n_rows: The number of rows to insert.
- *
- * Emits the "rows_inserted" signal on @sheet_model.
- **/
-void
-psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model,
- glong row, glong n_rows)
-{
- g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
-
- g_signal_emit (sheet_model, sheet_model_signals[ROWS_INSERTED], 0,
- row, n_rows);
-}
-
-
-/**
- * psppire_sheet_model_columns_inserted:
- * @sheet_model: A #PsppireSheetModel
- * @column: The column before which the new columns should be inserted.
- * @n_columns: The number of columns to insert.
- *
- * Emits the "columns_inserted" signal on @sheet_model.
- **/
-void
-psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model,
- glong column, glong n_columns)
-{
- g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
-
- g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_INSERTED], 0,
- column, n_columns);
-}
-
-
-
-
-/**
- * psppire_sheet_model_rows_deleted:
- * @sheet_model: A #PsppireSheetModel
- * @row: The first row to be deleted.
- * @n_rows: The number of rows to delete.
- *
- * Emits the "rows_deleted" signal on @sheet_model.
- **/
-void
-psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model,
- glong row, glong n_rows)
-{
- g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
-
- g_signal_emit (sheet_model, sheet_model_signals[ROWS_DELETED], 0,
- row, n_rows);
-}
-
-
-
-/**
- * psppire_sheet_model_columns_deleted:
- * @sheet_model: A #PsppireSheetModel
- * @column: The first column to be deleted.
- * @n_columns: The number of columns to delete.
- *
- * Emits the "columns_deleted" signal on @sheet_model.
- **/
-void
-psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model,
- glong column, glong n_columns)
-{
- g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
-
- g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_DELETED], 0,
- column, n_columns);
-}
-
-
-
-
-
-/**
- * psppire_sheet_model_is_editable:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns: TRUE if the cell is editable, FALSE otherwise
- **/
-gboolean
-psppire_sheet_model_is_editable (const PsppireSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), TRUE);
-
- if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable )
- return TRUE;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable (model,
- row, column);
-}
-
-
-/**
- * psppire_sheet_model_get_foreground:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns the foreground colour of the cell at @row, @column
- * The color is unallocated. It will be allocated by the viewing object.
- **/
-GdkColor *
-psppire_sheet_model_get_foreground (const PsppireSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground )
- return NULL;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground (model,
- row, column);
-}
-
-/**
- * psppire_sheet_model_get_background:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns the background colour of the cell at @row, @column
- * The color is unallocated. It will be allocated by the viewing object.
- **/
-GdkColor *
-psppire_sheet_model_get_background (const PsppireSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background )
- return NULL;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background (model,
- row, column);
-}
-
-/**
- * psppire_sheet_model_get_justification:
- * @sheet_model: A #PsppireSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns the justification of the cell at @row, @column
- * Returns: the justification, or NULL on error.
- **/
-const GtkJustification *
-psppire_sheet_model_get_justification (const PsppireSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification)
- return NULL;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification (model,
- row, column);
-}
-
-
-/**
- * psppire_sheet_model_get_column_count:
- * @model: A #PsppireSheetModel
- *
- * Returns the total number of columns represented by the model
- **/
-glong
-psppire_sheet_model_get_column_count (const PsppireSheetModel *model)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1);
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_count (model);
-}
-
-/**
- * psppire_sheet_model_get_row_count:
- * @model: A #PsppireSheetModel
- *
- * Returns the total number of rows represented by the model
- **/
-gint
-psppire_sheet_model_get_row_count(const PsppireSheetModel *model)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1);
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_count (model);
-}
-
-\f
-
-/* Column related functions */
-gboolean
-psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model, gint col)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE);
-
- if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity)
- return TRUE;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity (model, col);
-}
-
-
-gchar *
-psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model,
- gint col)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
- g_return_val_if_fail (col >= 0, NULL);
-
- if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle)
- return NULL;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle (model, col);
-}
-
-
-PsppireSheetButton *
-psppire_sheet_model_get_column_button (const PsppireSheetModel *model,
- gint col)
-{
- PsppireSheetButton *button = psppire_sheet_button_new ();
-
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title)
- button->label = PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title (model, col);
-
- return button;
-}
-
-GtkJustification
-psppire_sheet_model_get_column_justification (const PsppireSheetModel *model,
- gint col)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), GTK_JUSTIFY_LEFT);
-
- if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification)
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification (model, col);
-
- return GTK_JUSTIFY_LEFT;
-}
-
-\f
-
-gboolean
-psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model, gint row)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE);
-
- if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity)
- return TRUE;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity (model, row);
-}
-
-
-
-gchar *
-psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model,
- gint row)
-{
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle)
- return NULL;
-
- return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle (model, row);
-}
-
-
-PsppireSheetButton *
-psppire_sheet_model_get_row_button (const PsppireSheetModel *model,
- gint row)
-{
- PsppireSheetButton *button = psppire_sheet_button_new ();
-
- g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
-
- if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title)
- button->label = PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title (model, row);
-
- return button;
-}
-
+++ /dev/null
-/* PsppireSheetModel --- an abstract model for the PsppireSheet widget.
- * 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
- 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_SHEET_MODEL_H__
-#define __PSPPIRE_SHEET_MODEL_H__
-
-
-/* This file provides an abstract interface or the data displayed by the
- PsppireSheet widget */
-
-#include <glib-object.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-#include "gtkextra-sheet.h"
-
-G_BEGIN_DECLS
-
-#define PSPPIRE_TYPE_SHEET_MODEL (psppire_sheet_model_get_type ())
-#define PSPPIRE_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModel))
-#define PSPPIRE_IS_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_SHEET_MODEL))
-#define PSPPIRE_SHEET_MODEL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModelIface))
-
-typedef enum
-{
- PSPPIRE_SHEET_LEFT_BORDER = 1 << 0,
- PSPPIRE_SHEET_RIGHT_BORDER = 1 << 1,
- PSPPIRE_SHEET_TOP_BORDER = 1 << 2,
- PSPPIRE_SHEET_BOTTOM_BORDER = 1 << 3
-} PsppireSheetBorderType ;
-
-
-typedef struct _PsppireSheetModel PsppireSheetModel; /* Dummy typedef */
-typedef struct _PsppireSheetModelIface PsppireSheetModelIface;
-typedef struct _PsppireSheetRange PsppireSheetRange;
-typedef struct _PsppireSheetCellBorder PsppireSheetCellBorder;
-
-struct _PsppireSheetRange
-{
- gint row0, col0; /* upper-left cell */
- gint rowi, coli; /* lower-right cell */
-};
-
-struct _PsppireSheetCellBorder
-{
- PsppireSheetBorderType mask;
- guint width;
- GdkLineStyle line_style;
- GdkCapStyle cap_style;
- GdkJoinStyle join_style;
- GdkColor color;
-};
-
-
-
-struct _PsppireSheetModelIface
-{
- GTypeInterface g_iface;
-
- gboolean free_strings;
-
- /* Signals */
- void (* range_changed) (PsppireSheetModel *sheet_model,
- glong row0, glong col0,
- glong rowi, glong coli);
-
- void (* rows_inserted) (PsppireSheetModel *sheet_model,
- glong row, glong n_rows);
-
- void (* rows_deleted) (PsppireSheetModel *sheet_model,
- glong row, glong n_rows);
-
- void (* columns_inserted) (PsppireSheetModel *sheet_model,
- glong column, glong n_columns);
-
- void (* columns_deleted) (PsppireSheetModel *sheet_model,
- glong column, glong n_columns);
-
-
-
- /* Virtual Table */
-
- gchar * (* get_string) (const PsppireSheetModel *sheet_model,
- glong row, glong column);
-
- gboolean (* set_string) (PsppireSheetModel *sheet_model,
- const gchar *s, glong row, glong column);
-
- gboolean (* clear_datum) (PsppireSheetModel *sheet_model,
- glong row, glong column);
-
- gboolean (* is_editable) (const PsppireSheetModel *sheet_model, glong row, glong column);
-
- GdkColor * (* get_foreground) (const PsppireSheetModel *sheet_model,
- glong row, glong column);
-
- GdkColor * (* get_background) (const PsppireSheetModel *sheet_model,
- glong row, glong column);
-
- const GtkJustification * (* get_justification) (const PsppireSheetModel *sheet_model,
- glong row, glong column);
-
- /* column related metadata */
-
- gchar * (*get_column_title) (const PsppireSheetModel *, gint col);
- gchar * (*get_column_subtitle) (const PsppireSheetModel *, gint col);
- gboolean (*get_column_sensitivity) (const PsppireSheetModel *, gint col);
- GtkJustification (*get_column_justification) (const PsppireSheetModel *mode, gint col);
- const PsppireSheetButton * (* get_button) (const PsppireSheetModel *model, gint col);
-
- glong (*get_column_count) (const PsppireSheetModel *model);
-
-
- /* row related metadata */
- gchar * (*get_row_title) (const PsppireSheetModel *, gint row);
- gchar * (*get_row_subtitle) (const PsppireSheetModel *, gint row);
- glong (*get_row_count) (const PsppireSheetModel *model);
- gboolean (*get_row_sensitivity) (const PsppireSheetModel *, gint row);
-};
-
-
-
-GType psppire_sheet_model_get_type (void) G_GNUC_CONST;
-
-
-gchar * psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model,
- glong row, glong column);
-
-gboolean psppire_sheet_model_set_string (PsppireSheetModel *sheet_model,
- const gchar *s,
- glong row, glong column);
-
-gboolean psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model,
- glong row, glong column);
-
-
-void psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model,
- glong row0, glong col0,
- glong rowi, glong coli);
-
-void psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model,
- glong row, glong n_rows);
-
-void psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model,
- glong row, glong n_rows);
-
-void psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model,
- glong column, glong n_columns);
-
-void psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model,
- glong column, glong n_columns);
-
-
-gboolean psppire_sheet_model_is_editable (const PsppireSheetModel *model,
- glong row, glong column);
-
-gboolean psppire_sheet_model_is_visible
- (const PsppireSheetModel *model, glong row, glong column);
-
-
-GdkColor *psppire_sheet_model_get_foreground
- (const PsppireSheetModel *model, glong row, glong column);
-
-GdkColor *psppire_sheet_model_get_background
- (const PsppireSheetModel *model, glong row, glong column);
-
-const GtkJustification *psppire_sheet_model_get_justification
- (const PsppireSheetModel *model, glong row, glong column);
-
-const PsppireSheetCellBorder * psppire_sheet_model_get_cell_border
- (const PsppireSheetModel *model, glong row, glong column);
-
-gboolean psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model);
-
-glong psppire_sheet_model_get_column_count (const PsppireSheetModel *sheet_model);
-
-gint psppire_sheet_model_get_row_count (const PsppireSheetModel *sheet_model);
-
-\f
-
-gboolean psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model,
- gint col);
-
-gchar * psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model,
- gint col);
-
-PsppireSheetButton * psppire_sheet_model_get_column_button (const PsppireSheetModel *, gint);
-
-GtkJustification psppire_sheet_model_get_column_justification (const PsppireSheetModel *,
- gint);
-
-\f
-
-gboolean psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model,
- gint row);
-
-
-gchar * psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model,
- gint row);
-
-
-PsppireSheetButton * psppire_sheet_model_get_row_button (const PsppireSheetModel *, gint);
-
-
-
-
-G_END_DECLS
-
-#endif /* __PSPPIRE_SHEET_MODEL_H__ */
## Process this file with automake to produce Makefile.in -*- makefile -*-
+include $(top_srcdir)/src/ui/gui/sheet/automake.mk
+
bin_PROGRAMS += src/ui/gui/psppire
src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GLADE_CFLAGS) -Wall \
src_ui_gui_psppire_LDADD = \
-dlopen src/ui/gui/libpsppire.la \
src/ui/gui/libpsppwidgets.la \
+ src/ui/gui/sheet/libsheet.la \
lib/gtksheet/libgtksheet.a \
src/ui/libuicommon.la \
src/libpspp.la \
#include <language/syntax-string-source.h>
#include "psppire-data-store.h"
-#include <gtksheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis-impl.h>
#include "helper.h"
#include <gtksheet/gtkxpaned.h>
#include <glib-object.h>
#include <gtk/gtknotebook.h>
-#include <lib/gtksheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis-impl.h>
#include "psppire-var-store.h"
#include "psppire-data-store.h"
#include <data/data-out.h>
#include <data/variable.h>
-#include <gtksheet/psppire-sheetmodel.h>
+#include <ui/gui/sheet/psppire-sheetmodel.h>
#include <ui/gui/psppire-marshal.h>
#include <pango/pango-context.h>
#include <config.h>
#include "psppire-var-sheet.h"
-#include <gtksheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis-impl.h>
#include <glade/glade.h>
#include "helper.h"
#include <gobject/gvaluecollector.h>
-#include <gtksheet/psppire-sheetmodel.h>
+#include <ui/gui/sheet/psppire-sheetmodel.h>
#include "psppire-var-store.h"
#include "helper.h"
--- /dev/null
+## Process this file with automake to produce Makefile.in -*- makefile -*-
+
+noinst_LTLIBRARIES += src/ui/gui/sheet/libsheet.la
+
+src_ui_gui_sheet_libsheet_la_CFLAGS = $(GTK_CFLAGS)
+
+src_ui_gui_sheet_libsheet_la_SOURCES = \
+ src/ui/gui/sheet/psppire-axis.c \
+ src/ui/gui/sheet/psppire-axis.h \
+ src/ui/gui/sheet/psppire-axis-impl.c \
+ src/ui/gui/sheet/psppire-axis-impl.h \
+ src/ui/gui/sheet/psppire-sheetmodel.c \
+ src/ui/gui/sheet/psppire-sheetmodel.h
+
--- /dev/null
+/* 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;
+};
+
+void
+psppire_axis_impl_dump (const PsppireAxisImpl *a)
+{
+ struct tower_node *n = tower_first (&a->unit_tower);
+
+ g_debug ("Axis %p", a);
+ while (n)
+ {
+ const struct axis_node *an = tower_data (n, struct axis_node, unit_node);
+ const struct tower_node *pn = &an->pixel_node;
+ g_debug ("%ld units of height %g",
+ n->size, pn->size / (float) n->size);
+
+ n = tower_next (&a->unit_tower, n);
+ }
+ g_debug ("\n");
+}
+
+static gint
+unit_at_pixel (const PsppireAxis *axis, glong pixel)
+{
+ PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+
+ unsigned long int start;
+ struct tower_node *n;
+ struct axis_node *an;
+ gfloat fraction;
+
+ g_return_val_if_fail (pixel >= 0, -1);
+
+ n = tower_lookup (&a->pixel_tower, pixel, &start);
+ an = tower_data (n, struct axis_node, pixel_node);
+
+ 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
+start_pixel (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 resize (PsppireAxis *axis, gint posn, glong size);
+
+
+
+static void
+psppire_impl_iface_init (PsppireAxisIface *iface)
+{
+ iface->unit_size = unit_size;
+ iface->unit_count = unit_count;
+ iface->start_pixel = start_pixel;
+ iface->unit_at_pixel = unit_at_pixel;
+ iface->total_size = total_size;
+ iface->resize = resize;
+}
+
+/* --- 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;
+
+ if (n_units == 0)
+ return;
+
+ node = pool_malloc (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;
+ struct axis_node *existing_node;
+
+ g_return_if_fail (posn <= tower_height (&a->unit_tower));
+
+ /* Nothing needs to be done */
+ if ( posn == 0 || posn == tower_height (&a->unit_tower))
+ return;
+
+ n = tower_lookup (&a->unit_tower, posn, &start);
+
+ 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_malloc (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 axis_node *before = NULL;
+ struct axis_node *new_node;
+
+ g_return_if_fail ( posn >= 0);
+ g_return_if_fail ( posn <= tower_height (&a->unit_tower));
+
+ if ( posn < tower_height (&a->unit_tower))
+ {
+ unsigned long int start = 0;
+ struct tower_node *n;
+
+ split (a, posn);
+
+ n = tower_lookup (&a->unit_tower, posn, &start);
+ g_assert (posn == start);
+
+ before = tower_data (n, struct axis_node, unit_node);
+ }
+
+ new_node = pool_malloc (a->pool, sizeof (*new_node));
+
+ tower_insert (&a->unit_tower,
+ 1,
+ &new_node->unit_node,
+ before ? &before->unit_node : NULL);
+
+ tower_insert (&a->pixel_tower,
+ size,
+ &new_node->pixel_node,
+ before ? &before->pixel_node : NULL);
+}
+
+
+/* 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;
+
+ g_return_val_if_fail (posn < tower_height (&a->unit_tower), NULL);
+
+ 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);
+}
+
+
+static void
+resize (PsppireAxis *axis, gint posn, glong size)
+{
+ PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
+
+ struct axis_node *an;
+ g_return_if_fail (posn >= 0);
+ g_return_if_fail (size > 0);
+
+ /* Silently ignore this request if the position is greater than the number of
+ units in the axis */
+ if (posn >= tower_height (&a->unit_tower))
+ return ;
+
+ an = make_single (a, posn);
+
+ tower_resize (&a->pixel_tower, &an->pixel_node, size);
+}
+
+
+void
+psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size)
+{
+ resize (PSPPIRE_AXIS (a), posn, 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_units)
+{
+ gint units_to_delete = n_units;
+ unsigned long int start;
+ struct tower_node *unit_node ;
+ g_return_if_fail (first + n_units <= tower_height (&a->unit_tower));
+
+ split (a, first);
+ split (a, first + n_units);
+
+ unit_node = tower_lookup (&a->unit_tower, first, &start);
+ g_assert (start == first);
+
+ while (units_to_delete > 0)
+ {
+ struct tower_node *next_unit_node;
+ struct axis_node *an = tower_data (unit_node,
+ struct axis_node, unit_node);
+
+ g_assert (unit_node == &an->unit_node);
+ g_assert (unit_node->size <= n_units);
+
+ units_to_delete -= unit_node->size;
+
+ next_unit_node = tower_next (&a->unit_tower, unit_node);
+
+ tower_delete (&a->unit_tower, unit_node);
+ tower_delete (&a->pixel_tower, &an->pixel_node);
+
+ pool_free (a->pool, an);
+
+ unit_node = next_unit_node;
+ }
+}
--- /dev/null
+/* 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__ */
--- /dev/null
+/* 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 <libpspp/misc.h>
+#include "psppire-axis.h"
+#include <ui/gui/psppire-marshal.h>
+#include <gtk/gtk.h>
+
+
+
+/* Signals */
+enum
+ {
+ RESIZE_UNIT,
+ n_signals
+ };
+
+static guint signals[n_signals] ;
+
+
+#define PSPPIRE_AXIS_GET_IFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_AXIS_IFACE, PsppireAxisIface))
+
+GType
+psppire_axis_iface_get_type (void)
+{
+ static GType psppire_axis_iface_type = 0;
+
+ if (! psppire_axis_iface_type)
+ {
+ static const GTypeInfo psppire_axis_iface_info =
+ {
+ sizeof (PsppireAxisIface), /* class_size */
+ NULL, /* base init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ psppire_axis_iface_type =
+ g_type_register_static (G_TYPE_INTERFACE, "PsppireAxisIface",
+ &psppire_axis_iface_info, 0);
+ }
+
+ return psppire_axis_iface_type;
+}
+
+G_DEFINE_ABSTRACT_TYPE(PsppireAxis, psppire_axis, G_TYPE_OBJECT);
+
+
+
+/* --- 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;
+
+
+
+enum
+ {
+ PROP_0,
+ PROP_MIN_EXTENT,
+ PROP_DEFAULT_SIZE
+ };
+
+
+static void
+psppire_axis_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PsppireAxis *axis = PSPPIRE_AXIS (object);
+
+ switch (prop_id)
+ {
+ case PROP_MIN_EXTENT:
+ g_value_set_long (value, axis->min_extent);
+ break;
+ case PROP_DEFAULT_SIZE:
+ g_value_set_int (value, axis->default_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ };
+}
+
+
+static void
+psppire_axis_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PsppireAxis *axis = PSPPIRE_AXIS (object);
+
+ switch (prop_id)
+ {
+ case PROP_MIN_EXTENT:
+ axis->min_extent = g_value_get_long (value);
+ break;
+ case PROP_DEFAULT_SIZE:
+ axis->default_size = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ };
+}
+
+static void
+psppire_axis_class_init (PsppireAxisClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GParamSpec *min_extent_spec;
+ GParamSpec *default_size_spec;
+
+ object_class->set_property = psppire_axis_set_property;
+ object_class->get_property = psppire_axis_get_property;
+
+ min_extent_spec =
+ g_param_spec_long ("minimum-extent",
+ "Minimum Extent",
+ "The smallest extent to which the axis will provide units (typically set to the height/width of the associated widget).",
+ 0, G_MAXLONG,
+ 0,
+ G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE );
+
+ g_object_class_install_property (object_class,
+ PROP_MIN_EXTENT,
+ min_extent_spec);
+
+
+ default_size_spec =
+ g_param_spec_int ("default-size",
+ "Default Size",
+ "The size given to units which haven't been explicity inserted",
+ 0, G_MAXINT,
+ 25,
+ G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE );
+
+
+ g_object_class_install_property (object_class,
+ PROP_DEFAULT_SIZE,
+ default_size_spec);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = psppire_axis_finalize;
+
+
+ signals[RESIZE_UNIT] =
+ g_signal_new ("resize-unit",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ psppire_marshal_VOID__INT_LONG,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_LONG
+ );
+}
+
+
+static void
+psppire_axis_init (PsppireAxis *axis)
+{
+}
+
+
+static void
+psppire_axis_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+gint
+psppire_axis_unit_size (const PsppireAxis *a, gint unit)
+{
+ g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+
+ g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_size, -1);
+
+
+ if (unit >= PSPPIRE_AXIS_GET_IFACE (a)->unit_count(a))
+ return a->default_size;
+
+ return PSPPIRE_AXIS_GET_IFACE (a)->unit_size (a, unit);
+}
+
+gint
+psppire_axis_unit_count (const PsppireAxis *a)
+{
+ glong padding = 0;
+ glong actual_size;
+
+ g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+ g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_count, -1);
+
+ actual_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+
+ if ( actual_size < a->min_extent )
+ padding = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
+
+ return PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a) + padding;
+}
+
+
+/* Return the starting pixel of UNIT */
+glong
+psppire_axis_start_pixel (const PsppireAxis *a, gint unit)
+{
+ gint the_count, total_size ;
+ g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+
+ the_count = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
+ total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+
+ if ( unit >= the_count)
+ {
+ return total_size + (unit - the_count) * a->default_size;
+ }
+
+ return PSPPIRE_AXIS_GET_IFACE (a)->start_pixel (a, unit);
+}
+
+
+/* Return the unit covered by PIXEL */
+gint
+psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
+{
+ glong total_size;
+
+ g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+
+ g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a), -1);
+
+ g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel, -1);
+
+ total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+
+ if (pixel >= total_size)
+ {
+ gint n_items = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
+ glong extra = pixel - total_size;
+
+ return n_items - 1 + DIV_RND_UP (extra, a->default_size);
+ }
+
+ return PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel (a, pixel);
+}
+
+
+/* Set UNIT to size SIZE */
+void
+psppire_axis_resize (PsppireAxis *a, gint unit, glong size)
+{
+ g_return_if_fail (PSPPIRE_IS_AXIS (a));
+
+ g_return_if_fail (PSPPIRE_AXIS_GET_IFACE (a));
+
+ g_return_if_fail (size > 0);
+
+ if (PSPPIRE_AXIS_GET_IFACE (a)->resize)
+ PSPPIRE_AXIS_GET_IFACE (a)->resize (a, unit, size);
+
+
+ g_signal_emit (a, signals [RESIZE_UNIT], 0, unit, size);
+}
+
+
--- /dev/null
+/* 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_H__
+#define PSPPIRE_AXIS_H__
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+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 _PsppireAxis
+{
+ GObject parent;
+
+ glong min_extent;
+ gint default_size;
+};
+
+struct _PsppireAxisClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType psppire_axis_get_type (void);
+
+
+\f
+
+GType psppire_axis_iface_get_type (void);
+
+#define PSPPIRE_TYPE_AXIS_IFACE (psppire_axis_iface_get_type ())
+
+typedef struct _PsppireAxisIface PsppireAxisIface;
+
+struct _PsppireAxisIface
+{
+ GTypeInterface g_iface;
+
+
+ /* Virtual Table */
+
+ gint (*unit_size) (const PsppireAxis *a, gint unit);
+
+ gint (*unit_count) (const PsppireAxis *a);
+
+ glong (*start_pixel) (const PsppireAxis *a, gint unit);
+
+ gint (*unit_at_pixel) (const PsppireAxis *a, glong pixel);
+
+ glong (*total_size) (const PsppireAxis *a);
+
+
+ void (*resize) (PsppireAxis *a, gint unit, glong pixels);
+};
+
+
+/* Interface between sheet and axis */
+
+gint psppire_axis_unit_size (const PsppireAxis *a, gint unit);
+
+gint psppire_axis_unit_count (const PsppireAxis *a);
+
+glong psppire_axis_start_pixel (const PsppireAxis *a, gint unit);
+
+gint psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel);
+
+
+void psppire_axis_resize (PsppireAxis *a, gint unit, glong size);
+
+G_END_DECLS
+
+#endif /* PSPPIRE_AXIS_H__ */
--- /dev/null
+/* PsppireSheetModel --- an abstract model for the PsppireSheet widget.
+ * 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
+ 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 <glib.h>
+#include "psppire-sheetmodel.h"
+#include <ui/gui/psppire-marshal.h>
+
+enum {
+ RANGE_CHANGED,
+ ROWS_INSERTED,
+ ROWS_DELETED,
+ COLUMNS_INSERTED,
+ COLUMNS_DELETED,
+ LAST_SIGNAL
+};
+
+static guint sheet_model_signals[LAST_SIGNAL] = { 0 };
+
+
+static void psppire_sheet_model_base_init (gpointer g_class);
+
+
+GType
+psppire_sheet_model_get_type (void)
+{
+ static GType sheet_model_type = 0;
+
+ if (! sheet_model_type)
+ {
+ static const GTypeInfo sheet_model_info =
+ {
+ sizeof (PsppireSheetModelIface), /* class_size */
+ psppire_sheet_model_base_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ sheet_model_type =
+ g_type_register_static (G_TYPE_INTERFACE, "PsppireSheetModel",
+ &sheet_model_info, 0);
+
+ g_type_interface_add_prerequisite (sheet_model_type, G_TYPE_OBJECT);
+ }
+
+ return sheet_model_type;
+}
+
+static void
+psppire_sheet_model_base_init (gpointer g_class)
+{
+ static gboolean initialized = FALSE;
+
+ if (! initialized)
+ {
+ sheet_model_signals[RANGE_CHANGED] =
+ g_signal_new ("range_changed",
+ PSPPIRE_TYPE_SHEET_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppireSheetModelIface, range_changed),
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT_INT_INT,
+ G_TYPE_NONE, 4,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+
+
+ sheet_model_signals[ROWS_INSERTED] =
+ g_signal_new ("rows_inserted",
+ PSPPIRE_TYPE_SHEET_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppireSheetModelIface, rows_inserted),
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+
+ sheet_model_signals[ROWS_DELETED] =
+ g_signal_new ("rows_deleted",
+ PSPPIRE_TYPE_SHEET_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppireSheetModelIface, rows_deleted),
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ sheet_model_signals[COLUMNS_INSERTED] =
+ g_signal_new ("columns_inserted",
+ PSPPIRE_TYPE_SHEET_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppireSheetModelIface, columns_inserted),
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+
+ sheet_model_signals[COLUMNS_DELETED] =
+ g_signal_new ("columns_deleted",
+ PSPPIRE_TYPE_SHEET_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PsppireSheetModelIface, columns_deleted),
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+
+ initialized = TRUE;
+ }
+}
+
+
+/**
+ * psppire_sheet_model_free_strings
+ * @sheet_model: A #PsppireSheetModel
+ *
+ * Returns: True if strings obtained with get_string should be freed by the
+ * sheet when no longer required.
+ **/
+gboolean
+psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->free_strings;
+}
+
+
+/**
+ * psppire_sheet_model_get_string:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row of the cell to be retrieved.
+ * @column: The column of the cell to be retrieved.
+ *
+ * Retrieves the datum at location ROW, COLUMN in the form of a string.
+ * Returns: The string representation of the datum, or NULL on error.
+ **/
+gchar *
+psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), 0);
+
+ g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string);
+
+ return (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string) (sheet_model, row, column);
+}
+
+/**
+ * psppire_sheet_model_set_string
+ * @sheet_model: A #PsppireSheetModel
+ * @text: The text describing the datum to be set.
+ * @row: The row of the cell to be cleared.
+ * @column: The column of the cell to be cleared.
+ *
+ * Sets the datum at a location from a string.
+ * Returns: TRUE if the datum was changed, FALSE otherwise.
+ **/
+gboolean
+psppire_sheet_model_set_string (PsppireSheetModel *sheet_model,
+ const gchar *text,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
+
+ g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string);
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string (sheet_model,
+ text, row, column);
+}
+
+
+
+/**
+ * psppire_sheet_model_datum_clear:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row of the cell to be cleared.
+ * @column: The column of the cell to be cleared.
+ *
+ * Called when the datum at a location is to be cleared.
+ * Returns: TRUE if the datum was cleared, FALSE otherwise.
+ **/
+gboolean
+psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE);
+
+ g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum);
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum (sheet_model,
+ row, column);
+}
+
+
+/**
+ * psppire_sheet_model_range_changed:
+ * @sheet_model: A #PsppireSheetModel
+ * @range: The #PsppireSheetRange range of cells which have changed.
+ *
+ * Emits the "range_changed" signal on @sheet_model.
+ **/
+void
+psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model,
+ glong row0, glong col0,
+ glong rowi, glong coli)
+{
+ g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
+
+ g_signal_emit (sheet_model, sheet_model_signals[RANGE_CHANGED], 0,
+ row0, col0, rowi, coli);
+}
+
+
+
+
+/**
+ * psppire_sheet_model_rows_inserted:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row before which the new rows should be inserted.
+ * @n_rows: The number of rows to insert.
+ *
+ * Emits the "rows_inserted" signal on @sheet_model.
+ **/
+void
+psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows)
+{
+ g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
+
+ g_signal_emit (sheet_model, sheet_model_signals[ROWS_INSERTED], 0,
+ row, n_rows);
+}
+
+
+/**
+ * psppire_sheet_model_columns_inserted:
+ * @sheet_model: A #PsppireSheetModel
+ * @column: The column before which the new columns should be inserted.
+ * @n_columns: The number of columns to insert.
+ *
+ * Emits the "columns_inserted" signal on @sheet_model.
+ **/
+void
+psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns)
+{
+ g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
+
+ g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_INSERTED], 0,
+ column, n_columns);
+}
+
+
+
+
+/**
+ * psppire_sheet_model_rows_deleted:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The first row to be deleted.
+ * @n_rows: The number of rows to delete.
+ *
+ * Emits the "rows_deleted" signal on @sheet_model.
+ **/
+void
+psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows)
+{
+ g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
+
+ g_signal_emit (sheet_model, sheet_model_signals[ROWS_DELETED], 0,
+ row, n_rows);
+}
+
+
+
+/**
+ * psppire_sheet_model_columns_deleted:
+ * @sheet_model: A #PsppireSheetModel
+ * @column: The first column to be deleted.
+ * @n_columns: The number of columns to delete.
+ *
+ * Emits the "columns_deleted" signal on @sheet_model.
+ **/
+void
+psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns)
+{
+ g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model));
+
+ g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_DELETED], 0,
+ column, n_columns);
+}
+
+
+
+
+
+/**
+ * psppire_sheet_model_is_editable:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row
+ * @column: The column
+ *
+ * Returns: TRUE if the cell is editable, FALSE otherwise
+ **/
+gboolean
+psppire_sheet_model_is_editable (const PsppireSheetModel *model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), TRUE);
+
+ if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable )
+ return TRUE;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable (model,
+ row, column);
+}
+
+
+/**
+ * psppire_sheet_model_get_foreground:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row
+ * @column: The column
+ *
+ * Returns the foreground colour of the cell at @row, @column
+ * The color is unallocated. It will be allocated by the viewing object.
+ **/
+GdkColor *
+psppire_sheet_model_get_foreground (const PsppireSheetModel *model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground )
+ return NULL;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground (model,
+ row, column);
+}
+
+/**
+ * psppire_sheet_model_get_background:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row
+ * @column: The column
+ *
+ * Returns the background colour of the cell at @row, @column
+ * The color is unallocated. It will be allocated by the viewing object.
+ **/
+GdkColor *
+psppire_sheet_model_get_background (const PsppireSheetModel *model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background )
+ return NULL;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background (model,
+ row, column);
+}
+
+/**
+ * psppire_sheet_model_get_justification:
+ * @sheet_model: A #PsppireSheetModel
+ * @row: The row
+ * @column: The column
+ *
+ * Returns the justification of the cell at @row, @column
+ * Returns: the justification, or NULL on error.
+ **/
+const GtkJustification *
+psppire_sheet_model_get_justification (const PsppireSheetModel *model,
+ glong row, glong column)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification)
+ return NULL;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification (model,
+ row, column);
+}
+
+
+/**
+ * psppire_sheet_model_get_column_count:
+ * @model: A #PsppireSheetModel
+ *
+ * Returns the total number of columns represented by the model
+ **/
+glong
+psppire_sheet_model_get_column_count (const PsppireSheetModel *model)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1);
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_count (model);
+}
+
+/**
+ * psppire_sheet_model_get_row_count:
+ * @model: A #PsppireSheetModel
+ *
+ * Returns the total number of rows represented by the model
+ **/
+gint
+psppire_sheet_model_get_row_count(const PsppireSheetModel *model)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1);
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_count (model);
+}
+
+\f
+
+/* Column related functions */
+gboolean
+psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model, gint col)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE);
+
+ if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity)
+ return TRUE;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity (model, col);
+}
+
+
+gchar *
+psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model,
+ gint col)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+ g_return_val_if_fail (col >= 0, NULL);
+
+ if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle)
+ return NULL;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle (model, col);
+}
+
+
+PsppireSheetButton *
+psppire_sheet_model_get_column_button (const PsppireSheetModel *model,
+ gint col)
+{
+ PsppireSheetButton *button = psppire_sheet_button_new ();
+
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title)
+ button->label = PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title (model, col);
+
+ return button;
+}
+
+GtkJustification
+psppire_sheet_model_get_column_justification (const PsppireSheetModel *model,
+ gint col)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), GTK_JUSTIFY_LEFT);
+
+ if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification)
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification (model, col);
+
+ return GTK_JUSTIFY_LEFT;
+}
+
+\f
+
+gboolean
+psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model, gint row)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE);
+
+ if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity)
+ return TRUE;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity (model, row);
+}
+
+
+
+gchar *
+psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model,
+ gint row)
+{
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle)
+ return NULL;
+
+ return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle (model, row);
+}
+
+
+PsppireSheetButton *
+psppire_sheet_model_get_row_button (const PsppireSheetModel *model,
+ gint row)
+{
+ PsppireSheetButton *button = psppire_sheet_button_new ();
+
+ g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL);
+
+ if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title)
+ button->label = PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title (model, row);
+
+ return button;
+}
+
--- /dev/null
+/* PsppireSheetModel --- an abstract model for the PsppireSheet widget.
+ * 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
+ 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_SHEET_MODEL_H__
+#define __PSPPIRE_SHEET_MODEL_H__
+
+
+/* This file provides an abstract interface or the data displayed by the
+ PsppireSheet widget */
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <gtksheet/gtkextra-sheet.h>
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_TYPE_SHEET_MODEL (psppire_sheet_model_get_type ())
+#define PSPPIRE_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModel))
+#define PSPPIRE_IS_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_SHEET_MODEL))
+#define PSPPIRE_SHEET_MODEL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModelIface))
+
+typedef enum
+{
+ PSPPIRE_SHEET_LEFT_BORDER = 1 << 0,
+ PSPPIRE_SHEET_RIGHT_BORDER = 1 << 1,
+ PSPPIRE_SHEET_TOP_BORDER = 1 << 2,
+ PSPPIRE_SHEET_BOTTOM_BORDER = 1 << 3
+} PsppireSheetBorderType ;
+
+
+typedef struct _PsppireSheetModel PsppireSheetModel; /* Dummy typedef */
+typedef struct _PsppireSheetModelIface PsppireSheetModelIface;
+typedef struct _PsppireSheetRange PsppireSheetRange;
+typedef struct _PsppireSheetCellBorder PsppireSheetCellBorder;
+
+struct _PsppireSheetRange
+{
+ gint row0, col0; /* upper-left cell */
+ gint rowi, coli; /* lower-right cell */
+};
+
+struct _PsppireSheetCellBorder
+{
+ PsppireSheetBorderType mask;
+ guint width;
+ GdkLineStyle line_style;
+ GdkCapStyle cap_style;
+ GdkJoinStyle join_style;
+ GdkColor color;
+};
+
+
+
+struct _PsppireSheetModelIface
+{
+ GTypeInterface g_iface;
+
+ gboolean free_strings;
+
+ /* Signals */
+ void (* range_changed) (PsppireSheetModel *sheet_model,
+ glong row0, glong col0,
+ glong rowi, glong coli);
+
+ void (* rows_inserted) (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+ void (* rows_deleted) (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+ void (* columns_inserted) (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+ void (* columns_deleted) (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+
+
+ /* Virtual Table */
+
+ gchar * (* get_string) (const PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+ gboolean (* set_string) (PsppireSheetModel *sheet_model,
+ const gchar *s, glong row, glong column);
+
+ gboolean (* clear_datum) (PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+ gboolean (* is_editable) (const PsppireSheetModel *sheet_model, glong row, glong column);
+
+ GdkColor * (* get_foreground) (const PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+ GdkColor * (* get_background) (const PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+ const GtkJustification * (* get_justification) (const PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+ /* column related metadata */
+
+ gchar * (*get_column_title) (const PsppireSheetModel *, gint col);
+ gchar * (*get_column_subtitle) (const PsppireSheetModel *, gint col);
+ gboolean (*get_column_sensitivity) (const PsppireSheetModel *, gint col);
+ GtkJustification (*get_column_justification) (const PsppireSheetModel *mode, gint col);
+ const PsppireSheetButton * (* get_button) (const PsppireSheetModel *model, gint col);
+
+ glong (*get_column_count) (const PsppireSheetModel *model);
+
+
+ /* row related metadata */
+ gchar * (*get_row_title) (const PsppireSheetModel *, gint row);
+ gchar * (*get_row_subtitle) (const PsppireSheetModel *, gint row);
+ glong (*get_row_count) (const PsppireSheetModel *model);
+ gboolean (*get_row_sensitivity) (const PsppireSheetModel *, gint row);
+};
+
+
+
+GType psppire_sheet_model_get_type (void) G_GNUC_CONST;
+
+
+gchar * psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+gboolean psppire_sheet_model_set_string (PsppireSheetModel *sheet_model,
+ const gchar *s,
+ glong row, glong column);
+
+gboolean psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model,
+ glong row, glong column);
+
+
+void psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model,
+ glong row0, glong col0,
+ glong rowi, glong coli);
+
+void psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+void psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+void psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+void psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+
+gboolean psppire_sheet_model_is_editable (const PsppireSheetModel *model,
+ glong row, glong column);
+
+gboolean psppire_sheet_model_is_visible
+ (const PsppireSheetModel *model, glong row, glong column);
+
+
+GdkColor *psppire_sheet_model_get_foreground
+ (const PsppireSheetModel *model, glong row, glong column);
+
+GdkColor *psppire_sheet_model_get_background
+ (const PsppireSheetModel *model, glong row, glong column);
+
+const GtkJustification *psppire_sheet_model_get_justification
+ (const PsppireSheetModel *model, glong row, glong column);
+
+const PsppireSheetCellBorder * psppire_sheet_model_get_cell_border
+ (const PsppireSheetModel *model, glong row, glong column);
+
+gboolean psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model);
+
+glong psppire_sheet_model_get_column_count (const PsppireSheetModel *sheet_model);
+
+gint psppire_sheet_model_get_row_count (const PsppireSheetModel *sheet_model);
+
+\f
+
+gboolean psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model,
+ gint col);
+
+gchar * psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model,
+ gint col);
+
+PsppireSheetButton * psppire_sheet_model_get_column_button (const PsppireSheetModel *, gint);
+
+GtkJustification psppire_sheet_model_get_column_justification (const PsppireSheetModel *,
+ gint);
+
+\f
+
+gboolean psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model,
+ gint row);
+
+
+gchar * psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model,
+ gint row);
+
+
+PsppireSheetButton * psppire_sheet_model_get_row_button (const PsppireSheetModel *, gint);
+
+
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_SHEET_MODEL_H__ */