*.dirstamp
*.deps
*.la
+*.libs
--- /dev/null
+COMMENT -*-pspp-*- .
+
+COMMENT This program is useful for testing the behaviour of the Data and Variable Sheets.
+
+input program.
+vector var(500 F8.3).
+ loop #c = 1 to 1000.
+ loop #v = 1 to 500.
+ compute var(#v) = #v + #c / 1000.
+ end loop.
+ end case.
+ end loop.
+ end file.
+end input program.
+
+variable label var1 'First variable' var2 'Second variable' var3 'Third variable'.
+
+save outfile='grid.sav'.
+
+execute.
noinst_LIBRARIES += lib/gtksheet/libgtksheet.a
-lib_gtksheet_libgtksheet_a_CFLAGS = $(GTK_CFLAGS) -Wall
+AM_CPPFLAGS += -Ilib
+lib_gtksheet_libgtksheet_a_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
+
+nodist_lib_gtksheet_libgtksheet_a_SOURCES = \
+ lib/gtksheet/psppire-marshal.c \
+ lib/gtksheet/psppire-marshal.h
lib_gtksheet_libgtksheet_a_SOURCES = \
- lib/gtksheet/gsheet-column-iface.c \
- lib/gtksheet/gsheet-column-iface.h \
- lib/gtksheet/gsheet-hetero-column.c \
- lib/gtksheet/gsheet-hetero-column.h \
lib/gtksheet/gsheetmodel.c \
lib/gtksheet/gsheetmodel.h \
- lib/gtksheet/gsheet-row-iface.c \
- lib/gtksheet/gsheet-row-iface.h \
- lib/gtksheet/gsheet-uniform-column.c \
- lib/gtksheet/gsheet-uniform-column.h \
- lib/gtksheet/gsheet-uniform-row.c \
- lib/gtksheet/gsheet-uniform-row.h \
- lib/gtksheet/gtkextra.c \
- lib/gtksheet/gtkextrafeatures.h \
- lib/gtksheet/gtkextra-marshal.c \
- lib/gtksheet/gtkextra-marshal.h \
lib/gtksheet/gtkextra-sheet.h \
- lib/gtksheet/gtkitementry.h \
- lib/gtksheet/gtkitementry.c \
lib/gtksheet/gtksheet.c \
- lib/gtksheet/gtksheet.h
+ lib/gtksheet/gtksheet.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
+
EXTRA_DIST += lib/gtksheet/OChangeLog \
+ lib/gtksheet/marshaller-list \
lib/gtksheet/README
+
+lib/gtksheet/psppire-marshal.c: lib/gtksheet/marshaller-list
+ glib-genmarshal --body --prefix=psppire_marshal $< > $@
+
+lib/gtksheet/psppire-marshal.h: lib/gtksheet/marshaller-list
+ glib-genmarshal --header --prefix=psppire_marshal $< > $@
+
+BUILT_SOURCES += $(nodist_lib_gtksheet_libgtksheet_a_SOURCES)
+CLEANFILES += $(nodist_lib_gtksheet_libgtksheet_a_SOURCES)
+++ /dev/null
-/* GSheetColumn --- an abstract model of the column geometry of a
- GSheet widget.
-
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gprintf.h>
-#include <gobject/gvaluecollector.h>
-#include "gsheet-column-iface.h"
-#include "gtkextra-marshal.h"
-#include "gtkextra-sheet.h"
-
-enum {
- COLUMNS_CHANGED,
- LAST_SIGNAL
-};
-
-static guint sheet_column_signals[LAST_SIGNAL];
-
-
-
-static void g_sheet_column_base_init (gpointer g_class);
-
-
-GType
-g_sheet_column_get_type (void)
-{
- static GType sheet_column_type = 0;
-
- if (! sheet_column_type)
- {
- static const GTypeInfo sheet_column_info =
-
- {
- sizeof (GSheetColumnIface), /* class_size */
- g_sheet_column_base_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- sheet_column_type =
- g_type_register_static (G_TYPE_INTERFACE, "GSheetColumn",
- &sheet_column_info, 0);
-
- g_assert(sheet_column_type);
-
- g_type_interface_add_prerequisite (sheet_column_type, G_TYPE_OBJECT);
- }
-
- return sheet_column_type;
-}
-
-
-static void
-g_sheet_column_base_init (gpointer g_class)
-{
- static gboolean initialized = FALSE;
-
- if (! initialized)
- {
-
- sheet_column_signals[COLUMNS_CHANGED] =
- g_signal_new ("columns_changed",
- G_TYPE_SHEET_COLUMN,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSheetColumnIface, columns_changed),
- NULL, NULL,
- gtkextra_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
- initialized = TRUE;
- }
-}
-
-
-void
-g_sheet_column_set_width (GSheetColumn *column, glong col, gint size)
-{
- g_return_if_fail (G_IS_SHEET_COLUMN (column));
-
- if ((G_SHEET_COLUMN_GET_IFACE (column)->set_width) )
- (G_SHEET_COLUMN_GET_IFACE (column)->set_width) (column, col, size);
-}
-
-
-gint
-g_sheet_column_get_width (const GSheetColumn *column, glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
-
- g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_width);
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_width) (column, col);
-}
-
-
-
-gboolean
-g_sheet_column_get_visibility(const GSheetColumn *column,
- glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
-
- g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_visibility);
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_visibility) (column,
- col);
-
-}
-
-gboolean
-g_sheet_column_get_sensitivity(const GSheetColumn *column,
- glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
-
- g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity);
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_sensitivity) (column,
- col);
-
-}
-
-
-GtkSheetButton *
-g_sheet_column_get_button(const GSheetColumn *column,
- glong col)
-{
- GtkSheetButton *button = gtk_sheet_button_new();
-
- GSheetColumnIface *iface = G_SHEET_COLUMN_GET_IFACE (column);
-
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
-
- if ( iface->get_button_label)
- button->label = iface->get_button_label(column, col);
-
- return button;
-}
-
-GtkJustification
-g_sheet_column_get_justification(const GSheetColumn *column,
- glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
-
- g_assert (G_SHEET_COLUMN_GET_IFACE (column)->get_justification);
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_justification) (column, col);
-}
-
-gchar *
-g_sheet_column_get_subtitle (const GSheetColumn *column, glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), NULL);
-
- if ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_subtitle)
- return NULL;
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_subtitle) (column, col);
-}
-
-
-
-gint
-g_sheet_column_get_left_text_column (const GSheetColumn *column,
- glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
-
- if ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_left_text_column)
- return col;
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_left_text_column) (column, col);
-
-}
-
-gint
-g_sheet_column_get_right_text_column (const GSheetColumn *column,
- glong col)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (column), -1);
-
- if ( ! G_SHEET_COLUMN_GET_IFACE (column)->get_right_text_column)
- return col;
-
- return (G_SHEET_COLUMN_GET_IFACE (column)->get_right_text_column) (column, col);
-
-}
-
-void
-g_sheet_column_set_left_text_column (const GSheetColumn *column,
- glong col, gint i)
-{
- g_return_if_fail (G_IS_SHEET_COLUMN (column));
-
- if ( G_SHEET_COLUMN_GET_IFACE (column)->set_left_text_column)
- (G_SHEET_COLUMN_GET_IFACE (column)->set_left_text_column) (column, col, i);
-
-}
-
-
-void
-g_sheet_column_set_right_text_column (const GSheetColumn *column,
- glong col, gint i)
-{
- g_return_if_fail (G_IS_SHEET_COLUMN (column));
-
- if ( G_SHEET_COLUMN_GET_IFACE (column)->set_right_text_column)
- (G_SHEET_COLUMN_GET_IFACE (column)->set_right_text_column) (column, col, i);
-}
-
-glong
-g_sheet_column_get_column_count(const GSheetColumn *geo)
-{
- g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1);
-
- g_assert ( G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count);
-
- return (G_SHEET_COLUMN_GET_IFACE (geo)->get_column_count) (geo);
-}
-
-gint
-g_sheet_column_start_pixel(const GSheetColumn *geo, glong col)
-{
- gint i;
- gint start_pixel = 0;
-
- g_return_val_if_fail (G_IS_SHEET_COLUMN (geo), -1);
- g_return_val_if_fail (col <
- g_sheet_column_get_column_count(geo),-1);
-
- for ( i = 0 ; i < col ; ++i )
- {
- if ( g_sheet_column_get_visibility(geo, i))
- start_pixel += g_sheet_column_get_width(geo, i);
- }
-
- return start_pixel;
-
-}
-
-
-
-void
-g_sheet_column_columns_changed(GSheetColumn *geo,
- glong first, glong n_columns)
-{
- g_return_if_fail (G_IS_SHEET_COLUMN (geo));
-
- g_signal_emit (geo, sheet_column_signals[COLUMNS_CHANGED], 0,
- first, n_columns);
-}
-
-
-
-
+++ /dev/null
-/* GSheetColumn --- an abstract model of the column geometry of a
- * GSheet widget.
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GSHEET_COLUMN_IFACE_H
-#define __GSHEET_COLUMN_IFACE_H
-
-#include <glib-object.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#include "gtkextra-sheet.h"
-
-
-G_BEGIN_DECLS
-
-#define G_TYPE_SHEET_COLUMN (g_sheet_column_get_type ())
-#define G_SHEET_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SHEET_COLUMN, GSheetColumn))
-#define G_IS_SHEET_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SHEET_COLUMN))
-#define G_SHEET_COLUMN_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SHEET_COLUMN, GSheetColumnIface))
-
-
-typedef struct _GSheetColumn GSheetColumn;
-typedef struct _GSheetColumnIface GSheetColumnIface;
-struct _GSheetColumnIface
-{
- GTypeInterface g_iface;
-
-
- /* Signals */
- void (* columns_changed) (GSheetColumn *geo,
- glong col, glong n_columns);
-
- /* Virtual Table */
- gint (* get_width) (const GSheetColumn *gcolumn, glong col);
- void (* set_width) (GSheetColumn *gcolumn, glong col, gint width);
-
- gboolean (* get_visibility) (const GSheetColumn *gcolumn, glong col);
- gboolean (* get_sensitivity) (const GSheetColumn *gcolumn, glong col);
- const GtkSheetButton * (* get_button) (const GSheetColumn *gcolumn, glong col);
- GtkJustification (* get_justification) (const GSheetColumn *gcolumn, glong col);
-
- gint (*get_left_text_column) (const GSheetColumn *gcolumn,
- glong col);
-
- gint (*get_right_text_column) (const GSheetColumn *gcolumn,
- glong col);
-
- void (* set_left_text_column) (const GSheetColumn *gcolumn,
- glong col, gint i);
-
- void (* set_right_text_column) (const GSheetColumn *gcolumn,
- glong col, gint i);
-
- glong (* get_column_count) (const GSheetColumn *geo);
-
-
- GtkStateType (*get_button_state)(const GSheetColumn *geo, glong col);
- gchar * (*get_button_label)(const GSheetColumn *geo, glong col);
- gchar * (*get_subtitle)(const GSheetColumn *geo, glong col);
-
- gboolean (*get_button_visibility)(const GSheetColumn *geo,
- glong col);
- const GtkSheetChild * (*get_button_child)(const GSheetColumn *geo,
- glong col);
- GtkJustification * (*get_button_justification)(const GSheetColumn *geo,
- glong col);
-};
-
-
-inline GType g_sheet_column_get_type (void) G_GNUC_CONST;
-
-
-inline gint g_sheet_column_get_width (const GSheetColumn *gcolumn,
- glong col);
-
-
-inline void g_sheet_column_set_width (GSheetColumn *gcolumn,
- glong col, gint size);
-
-
-inline gboolean g_sheet_column_get_visibility (const GSheetColumn *gcolumn,
- glong col);
-
-inline gboolean g_sheet_column_get_sensitivity (const GSheetColumn *gcolumn,
- glong col);
-
-
-inline GtkSheetButton *g_sheet_column_get_button (const GSheetColumn *gcolumn,
- glong col);
-
-gchar *g_sheet_column_get_subtitle (const GSheetColumn *, glong);
-
-inline GtkJustification g_sheet_column_get_justification (const GSheetColumn *gcolumn, glong col);
-
-
-inline gint g_sheet_column_get_left_text_column (const GSheetColumn *gcolumn,
- glong col);
-
-inline gint g_sheet_column_get_right_text_column (const GSheetColumn *gcolumn,
- glong col);
-
-inline void g_sheet_column_set_left_text_column (const GSheetColumn *gcolumn,
- glong col, gint i);
-
-
-inline void g_sheet_column_set_right_text_column (const GSheetColumn *gcolumn,
- glong col, gint i);
-
-
-inline glong g_sheet_column_get_column_count (const GSheetColumn *geo);
-
-inline gint g_sheet_column_start_pixel (const GSheetColumn *geo, glong col);
-
-inline void g_sheet_column_columns_changed (GSheetColumn *geo,
- glong first, glong n_columns);
-
-G_END_DECLS
-
-#endif /* __G_SHEET_COLUMN_IFACE_H__ */
+++ /dev/null
-/* gsheet-hetero-column.c
- * PSPPIRE --- A Graphical User Interface for PSPP
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <config.h>
-
-#include "gsheet-column-iface.h"
-#include "gsheet-hetero-column.h"
-#include <string.h>
-
-
-static void g_sheet_hetero_column_init (GSheetHeteroColumn *hg);
-static void g_sheet_hetero_column_class_init (GSheetHeteroColumnClass *class);
-static void g_sheet_hetero_column_finalize (GObject *object);
-
-static void g_sheet_column_init (GSheetColumnIface *iface);
-
-
-static GObjectClass *parent_class = NULL;
-
-GType
-g_sheet_hetero_column_get_type (void)
-{
- static GType hetero_column_type = 0;
-
- if (!hetero_column_type)
- {
- static const GTypeInfo hetero_column_info =
- {
- sizeof (GSheetHeteroColumnClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) g_sheet_hetero_column_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GSheetHeteroColumn),
- 0,
- (GInstanceInitFunc) g_sheet_hetero_column_init,
- };
-
- static const GInterfaceInfo column_info =
- {
- (GInterfaceInitFunc) g_sheet_column_init,
- NULL,
- NULL
- };
-
- hetero_column_type =
- g_type_register_static (G_TYPE_OBJECT, "g_sheet_hetero_column",
- &hetero_column_info, 0);
-
- g_type_add_interface_static (hetero_column_type,
- G_TYPE_SHEET_COLUMN,
- &column_info);
- }
-
- return hetero_column_type;
-}
-
-
-static GtkSheetButton default_button;
-
-
-
-/**
- * g_sheet_hetero_column_new:
- * @width: The size of columns in this hetero column
- *
- * Return value: a new #g_sheet_hetero_column
- **/
-GObject *
-g_sheet_hetero_column_new (gint default_width, gint n_columns)
-{
- gint i;
- GSheetHeteroColumn *hg;
- GObject *retval;
-
- retval = g_object_new (G_TYPE_SHEET_HETERO_COLUMN, NULL);
-
- hg = G_SHEET_HETERO_COLUMN (retval);
- hg->n_columns = n_columns;
- hg->default_width = default_width;
- hg->col = g_new0 (struct GSheetHeteroColumnUnit, n_columns);
-
- for (i = 0 ; i < hg->n_columns; ++i )
- {
- hg->col[i].button = default_button;
- }
-
- return retval;
-}
-
-static gint
-g_sheet_hetero_column_get_width (const GSheetColumn *geom, glong i)
-{
- GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom);
-
- g_return_val_if_fail (i < hg->n_columns, -1);
-
- return hg->col[i].width;
-}
-
-static gboolean
-g_sheet_hetero_column_get_sensitivity (const GSheetColumn *geom, glong u)
-{
- return TRUE;
-}
-
-
-static gboolean
-g_sheet_hetero_column_get_visibility (const GSheetColumn *geom, glong u)
-{
- return TRUE;
-}
-
-
-
-static gchar *
-g_sheet_hetero_column_get_button_label (const GSheetColumn *geom, glong u)
-{
- GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom);
-
- return g_locale_to_utf8 (hg->col[u].button.label, -1, 0, 0, 0);
-}
-
-
-static GtkJustification
-g_sheet_hetero_column_get_justification (const GSheetColumn *geom, glong u)
-{
- return GTK_JUSTIFY_FILL;
-}
-
-
-
-static glong
-g_sheet_hetero_column_get_column_count (const GSheetColumn *geom)
-{
- GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geom);
-
- return hg->n_columns;
-}
-
-static void
-g_sheet_hetero_column_class_init (GSheetHeteroColumnClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
- object_class = (GObjectClass*) class;
-
- object_class->finalize = g_sheet_hetero_column_finalize;
-
- default_button.label=NULL;
- default_button.child=NULL;
- default_button.state=GTK_STATE_NORMAL;
- default_button.justification=GTK_JUSTIFY_CENTER;
- default_button.label_visible = TRUE;
-}
-
-
-static void
-g_sheet_hetero_column_init (GSheetHeteroColumn *o)
-{
-}
-
-static void
-g_sheet_hetero_column_finalize (GObject *object)
-{
- GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (object);
-
- g_free (hg->col);
-}
-
-static void
-hetero_column_set_width (GSheetColumn *geo, glong i, gint size)
-{
- GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN (geo);
-
- g_return_if_fail (i < hg->n_columns);
-
- hg->col[i].width = size;
-}
-
-
-
-static void
-g_sheet_column_init (GSheetColumnIface *iface)
-{
- iface->get_width = g_sheet_hetero_column_get_width ;
- iface->set_width = hetero_column_set_width ;
- iface->get_sensitivity = g_sheet_hetero_column_get_sensitivity ;
- iface->get_visibility = g_sheet_hetero_column_get_visibility ;
- iface->get_justification = g_sheet_hetero_column_get_justification;
- iface->get_column_count = g_sheet_hetero_column_get_column_count;
-
- iface->get_button_label = g_sheet_hetero_column_get_button_label;
-}
-
-
-void
-g_sheet_hetero_column_set_button_label (GSheetHeteroColumn *geo,
- glong i, const gchar *label)
-{
- g_return_if_fail (i < geo->n_columns);
-
- g_free (geo->col[i].button.label);
- geo->col[i].button.label = g_malloc (strlen (label) + 1);
-
- g_stpcpy (geo->col[i].button.label, label);
-}
-
-
-
-
-void
-g_sheet_hetero_column_set_width (GSheetHeteroColumn *geo, glong i, gint size)
-{
- GSheetColumn *iface = G_SHEET_COLUMN (geo);
-
- hetero_column_set_width (iface, i, size);
-}
-
-
-
+++ /dev/null
-/* GtkSheet widget for Gtk+.
- * Copyright (C) 2006 Free Software Foundation
-
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __G_SHEET_HETERO_COLUMN_H__
-#define __G_SHEET_HETERO_COLUMN_H__
-
-#include <glib-object.h>
-#include <glib.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define G_TYPE_SHEET_HETERO_COLUMN (g_sheet_hetero_column_get_type ())
-
-#define G_SHEET_HETERO_COLUMN(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, G_TYPE_SHEET_HETERO_COLUMN, GSheetHeteroColumn )
-#define G_SHEET_HETERO_COLUMN_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, g_sheet_hetero_column_get_type (), GSheetHeteroColumnClass)
-#define G_IS_SHEET_HETERO_COLUMN(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_SHEET_HETERO_COLUMN)
-
-
- struct GSheetHeteroColumnUnit
- {
- GtkSheetButton button;
-
- gint width;
- gboolean is_sensitive;
- gboolean is_visible;
- };
-
-
- struct _GSheetHeteroColumn{
- GObject parent;
-
- gint n_columns;
- gint default_width;
-
- struct GSheetHeteroColumnUnit *col;
-
- };
-
- struct _GSheetHeteroColumnClass
- {
- GObjectClass parent_class;
- };
-
-
-
-
- /* create a new column */
- GObject * g_sheet_hetero_column_new (gint default_width, gint n_columns);
-
- GType g_sheet_hetero_column_get_type (void);
-
-
- typedef struct _GSheetHeteroColumn GSheetHeteroColumn;
- typedef struct _GSheetHeteroColumnClass GSheetHeteroColumnClass;
-
-
- void g_sheet_hetero_column_set_button_label (GSheetHeteroColumn *geo,
- glong i, const gchar *label);
-
- void g_sheet_hetero_column_set_width (GSheetHeteroColumn *geo,
- glong i, gint size);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __G_SHEET_HETERO_COLUMN_H__ */
-
-
+++ /dev/null
-/* GSheetRow --- an abstract model of the row geometry of a
- * GSheet widget.
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gprintf.h>
-#include <gobject/gvaluecollector.h>
-#include "gsheet-row-iface.h"
-#include "gtkextra-marshal.h"
-
-
-enum {
- ROWS_CHANGED,
- LAST_SIGNAL
-};
-
-static guint sheet_row_signals[LAST_SIGNAL];
-
-
-
-static void g_sheet_row_base_init (gpointer g_class);
-
-
-GType
-g_sheet_row_get_type (void)
-{
- static GType sheet_row_type = 0;
-
- if (! sheet_row_type)
- {
- static const GTypeInfo sheet_row_info =
-
- {
- sizeof (GSheetRowIface), /* class_size */
- g_sheet_row_base_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- sheet_row_type =
- g_type_register_static (G_TYPE_INTERFACE, "GSheetRow",
- &sheet_row_info, 0);
-
- g_type_interface_add_prerequisite (sheet_row_type, G_TYPE_OBJECT);
- }
-
- return sheet_row_type;
-}
-
-
-static GtkSheetButton default_button;
-
-static void
-g_sheet_row_base_init (gpointer g_class)
-{
- static gboolean initialized = FALSE;
-
- if (! initialized)
- {
-
- sheet_row_signals[ROWS_CHANGED] =
- g_signal_new ("rows_changed",
- G_TYPE_SHEET_ROW,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSheetRowIface, rows_changed),
- NULL, NULL,
- gtkextra_VOID__INT_INT,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- G_TYPE_INT);
-
-
- default_button.state = GTK_STATE_NORMAL;
- default_button.label = NULL;
- default_button.label_visible = TRUE;
- default_button.child = NULL;
- default_button.justification = GTK_JUSTIFY_FILL;
-
- initialized = TRUE;
- }
-}
-
-void
-g_sheet_row_set_height (GSheetRow *row_geo,
- glong row, gint size)
-{
- g_return_if_fail (G_IS_SHEET_ROW (row_geo));
-
- if ((G_SHEET_ROW_GET_IFACE (row_geo)->set_height) )
- (G_SHEET_ROW_GET_IFACE (row_geo)->set_height) (row_geo, row,
- size);
-}
-
-
-gint
-g_sheet_row_get_height (const GSheetRow *row_geo,
- glong row)
-{
- g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), -1);
-
- g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_height);
-
- return (G_SHEET_ROW_GET_IFACE (row_geo)->get_height) (row_geo, row);
-}
-
-
-
-gboolean
-g_sheet_row_get_visibility(const GSheetRow *row_geo,
- glong row)
-{
- g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
-
- g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility);
-
- return (G_SHEET_ROW_GET_IFACE (row_geo)->get_visibility) (row_geo,
- row);
-
-}
-
-gboolean
-g_sheet_row_get_sensitivity(const GSheetRow *row_geo,
- glong row)
-{
- g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
-
- g_assert (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity);
-
- return (G_SHEET_ROW_GET_IFACE (row_geo)->get_sensitivity) (row_geo,
- row);
-
-}
-
-
-GtkSheetButton *
-g_sheet_row_get_button(const GSheetRow *row_geo,
- glong row)
-{
- GtkSheetButton *button = gtk_sheet_button_new();
-
- GSheetRowIface *iface = G_SHEET_ROW_GET_IFACE (row_geo);
-
- g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
-
- if ( iface->get_button_label)
- button->label = iface->get_button_label(row_geo, row);
-
- return button;
-}
-
-gchar *
-g_sheet_row_get_subtitle (const GSheetRow *row_geo, glong row)
-{
- g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), NULL);
-
- if ( ! G_SHEET_ROW_GET_IFACE (row_geo)->get_subtitle )
- return NULL;
-
- return (G_SHEET_ROW_GET_IFACE (row_geo)->get_subtitle) (row_geo, row);
-}
-
-
-
-
-glong
-g_sheet_row_get_row_count (const GSheetRow *geo)
-{
- g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
-
- g_assert ( G_SHEET_ROW_GET_IFACE (geo)->get_row_count);
-
- return (G_SHEET_ROW_GET_IFACE (geo)->get_row_count) (geo);
-}
-
-/**
- * g_sheet_row_start_pixel:
- * @geo: the row model
- * @row: the row number
- * @sheet: pointer to the sheet
- *
- * Returns the top y pixel for ROW.
- * Instances may override this method in order to achieve time and/or memory
- * optmisation.
- *
- * Returns: the y coordinate of the top of the row.
- */
-
-gint
-g_sheet_row_start_pixel(const GSheetRow *geo, glong row)
-{
- gint i;
- gint start_pixel = 0;
-
- g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
- g_return_val_if_fail (row >= 0, -1);
- g_return_val_if_fail (row <
- g_sheet_row_get_row_count(geo),-1);
-
- if ( G_SHEET_ROW_GET_IFACE(geo)->top_ypixel)
- return (G_SHEET_ROW_GET_IFACE(geo)->top_ypixel)(geo, row);
-
- for ( i = 0 ; i < row ; ++i )
- {
- if ( g_sheet_row_get_visibility(geo, i))
- start_pixel += g_sheet_row_get_height(geo, i);
- }
-
- return start_pixel;
-}
-
-
-glong
-g_sheet_row_pixel_to_row (const GSheetRow *geo, gint pixel)
-{
- gint i, cy;
- g_return_val_if_fail (G_IS_SHEET_ROW (geo), -1);
- g_return_val_if_fail (pixel >= 0, -1) ;
-
- if ( G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row)
- return (G_SHEET_ROW_GET_IFACE(geo)->pixel_to_row)(geo, pixel);
-
- cy = 0;
- for (i = 0; i < g_sheet_row_get_row_count (geo); ++i )
- {
- if (pixel >= cy &&
- pixel <= (cy + g_sheet_row_get_height (geo, i)) &&
- g_sheet_row_get_visibility (geo, i))
- return i;
-
- if(g_sheet_row_get_visibility (geo, i))
- cy += g_sheet_row_get_height (geo, i);
- }
-
- /* no match */
- return g_sheet_row_get_row_count (geo) - 1;
-}
-
-
-
-void
-g_sheet_row_rows_deleted (GSheetRow *geo,
- glong first, glong n_rows)
-{
- g_return_if_fail (G_IS_SHEET_ROW (geo));
-
- g_signal_emit (geo, sheet_row_signals[ROWS_CHANGED], 0,
- first, n_rows);
-}
+++ /dev/null
-/* GSheetRow --- an abstract model of the row geometry of a
- * GSheet widget.
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __G_SHEET_ROW_IFACE_H__
-#define __G_SHEET_ROW_IFACE_H__
-
-#include <glib-object.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#include "gtkextra-sheet.h"
-
-
-G_BEGIN_DECLS
-
-#define G_TYPE_SHEET_ROW (g_sheet_row_get_type ())
-#define G_SHEET_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SHEET_ROW, GSheetRow))
-#define G_IS_SHEET_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SHEET_ROW))
-#define G_SHEET_ROW_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SHEET_ROW, GSheetRowIface))
-
-
-
-
-typedef struct _GSheetRow GSheetRow;
-typedef struct _GSheetRowIface GSheetRowIface;
-
-struct _GSheetRowIface
-{
- GTypeInterface g_iface;
-
-
- /* Signals */
- void (* rows_changed) (GSheetRow *geo,
- glong row, glong n_rows);
-
- /* Virtual Table */
- gint (* get_height) (const GSheetRow *grow, glong row);
- void (* set_height) (GSheetRow *grow, glong row, gint height);
-
- gboolean (* get_visibility) (const GSheetRow *grow, glong row);
-
- gboolean (* get_sensitivity) (const GSheetRow *grow, glong row);
-
- const GtkSheetButton * (* get_button) (const GSheetRow *grow, glong row);
-
- glong (* get_row_count) (const GSheetRow *geo);
-
- GtkStateType (*get_button_state) (const GSheetRow *geo, glong row);
-
- gchar * (*get_button_label) (const GSheetRow *geo, glong row);
-
- gchar * (*get_subtitle) (const GSheetRow *geo, glong row);
-
- gboolean (*get_button_visibility) (const GSheetRow *geo,
- glong row);
-
- const GtkSheetChild * (*get_button_child) (const GSheetRow *geo,
- glong row);
-
- guint (*top_ypixel) (const GSheetRow *geo, glong row);
- glong (*pixel_to_row) (const GSheetRow *geo, guint pixel);
-};
-
-
-GType g_sheet_row_get_type (void) G_GNUC_CONST;
-
-
-gint g_sheet_row_get_height (const GSheetRow *grow,
- glong row);
-
-
-void g_sheet_row_set_height (GSheetRow *grow,
- glong row, gint size);
-
-
-gboolean g_sheet_row_get_visibility (const GSheetRow *grow,
- glong row);
-
-gboolean g_sheet_row_get_sensitivity (const GSheetRow *grow,
- glong row);
-
-
-GtkSheetButton *g_sheet_row_get_button (const GSheetRow *grow,
- glong row);
-
-
-glong g_sheet_row_get_row_count (const GSheetRow *geo);
-
-/* Return the top pixel of row ROW */
-gint g_sheet_row_start_pixel (const GSheetRow *geo, glong row);
-
-
-/* Return the row contained by pixel PIXEL */
-glong g_sheet_row_pixel_to_row (const GSheetRow *geo, gint pixel);
-
-
-void g_sheet_row_rows_deleted (GSheetRow *geo,
- glong first, glong n_rows);
-
-
-gchar *g_sheet_row_get_subtitle (const GSheetRow *row_geo, glong row);
-
-
-G_END_DECLS
-
-#endif /* __G_SHEET_ROW_IFACE_H__ */
+++ /dev/null
-/* gsheet-uniform-column.c
- *
- * PSPPIRE --- A Graphical User Interface for PSPP
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <config.h>
-
-#include "gsheet-column-iface.h"
-#include "gsheet-uniform-column.h"
-
-
-static void g_sheet_uniform_column_init (GSheetUniformColumn *ug);
-static void g_sheet_uniform_column_class_init (GSheetUniformColumnClass *class);
-static void g_sheet_uniform_column_finalize (GObject *object);
-
-static void g_sheet_column_init (GSheetColumnIface *iface);
-
-
-static GObjectClass *parent_class = NULL;
-
-GType
-g_sheet_uniform_column_get_type (void)
-{
- static GType uniform_column_type = 0;
-
- if (!uniform_column_type)
- {
- static const GTypeInfo uniform_column_info =
- {
- sizeof (GSheetUniformColumnClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) g_sheet_uniform_column_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GSheetUniformColumn),
- 0,
- (GInstanceInitFunc) g_sheet_uniform_column_init,
- };
-
- static const GInterfaceInfo column_info =
- {
- (GInterfaceInitFunc) g_sheet_column_init,
- NULL,
- NULL
- };
-
- uniform_column_type =
- g_type_register_static (G_TYPE_OBJECT, "g_sheet_uniform_column",
- &uniform_column_info, 0);
-
- g_type_add_interface_static (uniform_column_type,
- G_TYPE_SHEET_COLUMN,
- &column_info);
- }
-
- return uniform_column_type;
-}
-
-
-/**
- * g_sheet_uniform_column_new:
- * @width: The size of columns in this uniform column
- *
- * Return value: a new #g_sheet_uniform_column
- **/
-GObject *
-g_sheet_uniform_column_new (gint width, gint n_columns)
-{
- GSheetUniformColumn *ug;
- GObject *retval;
-
- retval = g_object_new (G_TYPE_SHEET_UNIFORM_COLUMN, NULL);
-
- ug = G_SHEET_UNIFORM_COLUMN(retval);
- ug->n_columns = n_columns;
- ug->width = width;
- ug->is_visible = TRUE;
- ug->is_sensitive = FALSE;
-
- return retval;
-}
-
-static gint
-g_sheet_uniform_column_get_width (const GSheetColumn *geom, glong u)
-{
- GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom);
-
- return ug->width;
-}
-
-static gboolean
-g_sheet_uniform_column_get_sensitivity (const GSheetColumn *geom, glong u)
-{
- GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom);
-
- return ug->is_sensitive;
-}
-
-
-static gboolean
-g_sheet_uniform_column_get_visibility (const GSheetColumn *geom, glong u)
-{
- GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom);
-
- return ug->is_visible;
-}
-
-
-static gchar *
-g_sheet_uniform_column_get_button_label (const GSheetColumn *geom, glong u)
-{
- gchar *label = g_strdup_printf ("%ld", u);
-
- return label;
-}
-
-
-static GtkJustification
-g_sheet_uniform_column_get_justification (const GSheetColumn *geom, glong u)
-{
- return GTK_JUSTIFY_FILL;
-}
-
-
-
-static glong
-g_sheet_uniform_column_get_column_count (const GSheetColumn *geom)
-{
- GSheetUniformColumn *ug = G_SHEET_UNIFORM_COLUMN (geom);
-
- return ug->n_columns;
-}
-
-static void
-g_sheet_uniform_column_class_init (GSheetUniformColumnClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
- object_class = (GObjectClass*) class;
-
- object_class->finalize = g_sheet_uniform_column_finalize;
-
-}
-
-
-static void
-g_sheet_uniform_column_init (GSheetUniformColumn *o)
-{
-}
-
-static void
-g_sheet_uniform_column_finalize (GObject *object)
-{
-}
-
-
-static void
-g_sheet_column_init (GSheetColumnIface *iface)
-{
- iface->get_width = g_sheet_uniform_column_get_width ;
- iface->get_sensitivity = g_sheet_uniform_column_get_sensitivity ;
- iface->get_visibility = g_sheet_uniform_column_get_visibility ;
- iface->get_justification = g_sheet_uniform_column_get_justification;
- iface->get_column_count = g_sheet_uniform_column_get_column_count;
- iface->get_button_label = g_sheet_uniform_column_get_button_label;
-}
-
+++ /dev/null
-/* GtkSheet widget for Gtk+.
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __G_SHEET_UNIFORM_COLUMN_H__
-#define __G_SHEET_UNIFORM_COLUMN_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define G_TYPE_SHEET_UNIFORM_COLUMN (g_sheet_uniform_column_get_type ())
-
-#define G_SHEET_UNIFORM_COLUMN(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, G_TYPE_SHEET_UNIFORM_COLUMN, GSheetUniformColumn )
-#define G_SHEET_UNIFORM_COLUMN_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, g_sheet_uniform_column_get_type (), GSheetUniformColumnClass)
-#define G_IS_SHEET_UNIFORM_COLUMN(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_SHEET_UNIFORM_COLUMN)
-
-
- struct _GSheetUniformColumn{
- GObject parent;
-
- gint n_columns;
- gint width;
- gboolean is_sensitive;
- gboolean is_visible;
- };
-
- struct _GSheetUniformColumnClass
- {
- GObjectClass parent_class;
- };
-
- /* create a new column */
- GObject * g_sheet_uniform_column_new (gint width, gint n_columns);
-
- GType g_sheet_uniform_column_get_type (void);
-
-
- typedef struct _GSheetUniformColumn GSheetUniformColumn;
- typedef struct _GSheetUniformColumnClass GSheetUniformColumnClass;
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __G_SHEET_UNIFORM_COLUMN_H__ */
-
-
+++ /dev/null
-/* gsheet-uniform-row.c
- *
- * PSPPIRE --- A Graphical User Interface for PSPP
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <config.h>
-
-#include "gsheet-row-iface.h"
-#include "gsheet-uniform-row.h"
-
-
-static void g_sheet_uniform_row_init (GSheetUniformRow *ug);
-static void g_sheet_uniform_row_class_init (GSheetUniformRowClass *class);
-static void g_sheet_uniform_row_finalize (GObject *object);
-
-static void g_sheet_row_init (GSheetRowIface *iface);
-
-
-static GObjectClass *parent_class = NULL;
-
-GType
-g_sheet_uniform_row_get_type (void)
-{
- static GType uniform_row_type = 0;
-
- if (!uniform_row_type)
- {
- static const GTypeInfo uniform_row_info =
- {
- sizeof (GSheetUniformRowClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) g_sheet_uniform_row_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GSheetUniformRow),
- 0,
- (GInstanceInitFunc) g_sheet_uniform_row_init,
- };
-
- static const GInterfaceInfo row_info =
- {
- (GInterfaceInitFunc) g_sheet_row_init,
- NULL,
- NULL
- };
-
- uniform_row_type =
- g_type_register_static (G_TYPE_OBJECT, "g_sheet_uniform_row",
- &uniform_row_info, 0);
-
- g_type_add_interface_static (uniform_row_type,
- G_TYPE_SHEET_ROW,
- &row_info);
- }
-
- return uniform_row_type;
-}
-
-
-/**
- * g_sheet_uniform_row_new:
- * @height: The size of rows in this uniform row
- *
- * Return value: a new #g_sheet_uniform_row
- **/
-GObject *
-g_sheet_uniform_row_new (gint height, gint n_rows)
-{
- GSheetUniformRow *ug;
- GObject *retval;
-
- retval = g_object_new (G_TYPE_SHEET_UNIFORM_ROW, NULL);
-
- ug = G_SHEET_UNIFORM_ROW(retval);
- ug->n_rows = n_rows;
- ug->height = height;
- ug->is_visible = TRUE;
-
- return retval;
-}
-
-static gint
-g_sheet_uniform_row_get_height (const GSheetRow *geom, glong u)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
-
- return ug->height;
-}
-
-static gboolean
-g_sheet_uniform_row_get_sensitivity (const GSheetRow *geom, glong u)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
-
- return (u < ug->n_rows);
-}
-
-
-static gboolean
-g_sheet_uniform_row_get_visibility (const GSheetRow *geom, glong u)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW (geom);
-
- return ug->is_visible;
-}
-
-
-static gchar *
-g_sheet_uniform_row_get_button_label (const GSheetRow *geom, glong u)
-{
- gchar *label = g_strdup_printf("%ld", u);
-
- return label;
-}
-
-
-
-static glong
-g_sheet_uniform_row_get_row_count (const GSheetRow *geom)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geom);
-
- return ug->n_rows;
-}
-
-
-static void
-g_sheet_uniform_row_class_init (GSheetUniformRowClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
- object_class = (GObjectClass*) class;
-
- object_class->finalize = g_sheet_uniform_row_finalize;
-
-}
-
-
-static void
-g_sheet_uniform_row_init (GSheetUniformRow *o)
-{
-}
-
-static void
-g_sheet_uniform_row_finalize (GObject *object)
-{
-}
-
-
-static guint
-g_sheet_uniform_row_top_ypixel (const GSheetRow *geo, glong row)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geo);
-
- return row * ug->height;
-}
-
-static glong
-g_sheet_uniform_row_pixel_to_row (const GSheetRow *geo, guint pixel)
-{
- GSheetUniformRow *ug = G_SHEET_UNIFORM_ROW(geo);
-
- gint row = pixel / ug->height;
-
- if (row >= g_sheet_uniform_row_get_row_count(geo))
- row = g_sheet_uniform_row_get_row_count(geo) - 1;
-
- return row;
-}
-
-
-
-static void
-g_sheet_row_init (GSheetRowIface *iface)
-{
- iface->get_height = g_sheet_uniform_row_get_height;
- iface->get_sensitivity = g_sheet_uniform_row_get_sensitivity ;
- iface->get_visibility = g_sheet_uniform_row_get_visibility;
- iface->get_row_count = g_sheet_uniform_row_get_row_count;
- iface->get_button_label = g_sheet_uniform_row_get_button_label;
- iface->top_ypixel = g_sheet_uniform_row_top_ypixel;
- iface->pixel_to_row = g_sheet_uniform_row_pixel_to_row;
-}
-
+++ /dev/null
-/* GtkSheet widget for Gtk+.
- * Copyright (C) 2006 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __G_SHEET_UNIFORM_ROW_H__
-#define __G_SHEET_UNIFORM_ROW_H__
-
-#include <glib-object.h>
-#include <glib.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define G_TYPE_SHEET_UNIFORM_ROW (g_sheet_uniform_row_get_type ())
-
-#define G_SHEET_UNIFORM_ROW(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, G_TYPE_SHEET_UNIFORM_ROW, GSheetUniformRow )
-#define G_SHEET_UNIFORM_ROW_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, g_sheet_uniform_row_get_type (), GSheetUniformRowClass)
-#define G_IS_SHEET_UNIFORM_ROW(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_SHEET_UNIFORM_ROW)
-
-
- struct _GSheetUniformRow{
- GObject parent;
-
- gint n_rows;
- gint height;
- gboolean is_visible;
- };
-
- struct _GSheetUniformRowClass
- {
- GObjectClass parent_class;
- };
-
- /* create a new row */
- GObject * g_sheet_uniform_row_new (gint height, gint n_rows);
-
- GType g_sheet_uniform_row_get_type (void);
-
-
- typedef struct _GSheetUniformRow GSheetUniformRow;
- typedef struct _GSheetUniformRowClass GSheetUniformRowClass;
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __G_SHEET_UNIFORM_ROW_H__ */
-
-
#include <glib.h>
#include "gsheetmodel.h"
-#include "gtkextra-marshal.h"
+#include <gtksheet/psppire-marshal.h>
enum {
RANGE_CHANGED,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSheetModelIface, range_changed),
NULL, NULL,
- gtkextra_VOID__INT_INT_INT_INT,
+ psppire_marshal_VOID__INT_INT_INT_INT,
G_TYPE_NONE, 4,
G_TYPE_INT,
G_TYPE_INT,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSheetModelIface, rows_inserted),
NULL, NULL,
- gtkextra_VOID__INT_INT,
+ psppire_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSheetModelIface, rows_deleted),
NULL, NULL,
- gtkextra_VOID__INT_INT,
+ psppire_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSheetModelIface, columns_inserted),
NULL, NULL,
- gtkextra_VOID__INT_INT,
+ psppire_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GSheetModelIface, columns_deleted),
NULL, NULL,
- gtkextra_VOID__INT_INT,
+ psppire_marshal_VOID__INT_INT,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
row, column);
}
-/**
- * g_sheet_model_is_visible:
- * @sheet_model: A #GSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns: TRUE if the cell is visible, FALSE otherwise
- **/
-gboolean
-g_sheet_model_is_visible (const GSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (G_IS_SHEET_MODEL (model), TRUE);
-
- if ( ! G_SHEET_MODEL_GET_IFACE (model)->is_visible )
- return TRUE;
-
- return G_SHEET_MODEL_GET_IFACE (model)->is_visible (model,
- row, column);
-}
-
/**
* g_sheet_model_get_foreground:
* @column: The column
*
* Returns the foreground colour of the cell at @row, @column
- * Returns: the foreground colour, or NULL on error.
+ * The color is unallocated. It will be allocated by the viewing object.
**/
-const GdkColor *
+GdkColor *
g_sheet_model_get_foreground (const GSheetModel *model,
glong row, glong column)
{
* @column: The column
*
* Returns the background colour of the cell at @row, @column
- * Returns: the background colour, or NULL on error.
+ * The color is unallocated. It will be allocated by the viewing object.
**/
-const GdkColor *
+GdkColor *
g_sheet_model_get_background (const GSheetModel *model,
glong row, glong column)
{
row, column);
}
-/**
- * g_sheet_model_get_font_desc:
- * @sheet_model: A #GSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns the font description of the cell at @row, @column
- * Returns: the font description, or NULL on error.
- **/
-const PangoFontDescription *
-g_sheet_model_get_font_desc(const GSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
- if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_font_desc)
- return NULL;
-
- return G_SHEET_MODEL_GET_IFACE (model)->get_font_desc (model,
- row, column);
-}
-
-/**
- * g_sheet_model_get_cell_border:
- * @sheet_model: A #GSheetModel
- * @row: The row
- * @column: The column
- *
- * Returns the cell border of the cell at @row, @column
- * Returns: the cell border, or NULL on error.
- **/
-const GtkSheetCellBorder *
-g_sheet_model_get_cell_border (const GSheetModel *model,
- glong row, glong column)
-{
- g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
- if ( ! G_SHEET_MODEL_GET_IFACE (model)->get_cell_border)
- return NULL;
-
- return G_SHEET_MODEL_GET_IFACE (model)->get_cell_border (model,
- row, column);
-}
-
-
/**
* g_sheet_model_get_column_count:
{
g_return_val_if_fail (G_IS_SHEET_MODEL (model), -1);
-
return G_SHEET_MODEL_GET_IFACE (model)->get_row_count (model);
}
+
+\f
+
+/* Column related functions */
+gboolean
+g_sheet_model_get_column_sensitivity (const GSheetModel *model, gint col)
+{
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), FALSE);
+
+ if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity)
+ return TRUE;
+
+ return G_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity (model, col);
+}
+
+
+gchar *
+g_sheet_model_get_column_subtitle (const GSheetModel *model,
+ gint col)
+{
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
+
+ if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle)
+ return NULL;
+
+ return G_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle (model, col);
+}
+
+
+GtkSheetButton *
+g_sheet_model_get_column_button (const GSheetModel *model,
+ gint col)
+{
+ GtkSheetButton *button = gtk_sheet_button_new ();
+
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
+
+ if ( G_SHEET_MODEL_GET_IFACE (model)->get_column_title)
+ button->label = G_SHEET_MODEL_GET_IFACE (model)->get_column_title (model, col);
+
+ return button;
+}
+
+GtkJustification
+g_sheet_model_get_column_justification (const GSheetModel *model,
+ gint col)
+{
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), GTK_JUSTIFY_LEFT);
+
+ if ( G_SHEET_MODEL_GET_IFACE (model)->get_column_justification)
+ return G_SHEET_MODEL_GET_IFACE (model)->get_column_justification (model, col);
+
+ return GTK_JUSTIFY_LEFT;
+}
+
+\f
+
+gboolean
+g_sheet_model_get_row_sensitivity (const GSheetModel *model, gint row)
+{
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), FALSE);
+
+ if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity)
+ return TRUE;
+
+ return G_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity (model, row);
+}
+
+
+
+gchar *
+g_sheet_model_get_row_subtitle (const GSheetModel *model,
+ gint row)
+{
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
+
+ if ( NULL == G_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle)
+ return NULL;
+
+ return G_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle (model, row);
+}
+
+
+GtkSheetButton *
+g_sheet_model_get_row_button (const GSheetModel *model,
+ gint row)
+{
+ GtkSheetButton *button = gtk_sheet_button_new ();
+
+ g_return_val_if_fail (G_IS_SHEET_MODEL (model), NULL);
+
+ if ( G_SHEET_MODEL_GET_IFACE (model)->get_row_title)
+ button->label = G_SHEET_MODEL_GET_IFACE (model)->get_row_title (model, row);
+
+ return button;
+}
+
#include <glib-object.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
-
+#include "gtkextra-sheet.h"
G_BEGIN_DECLS
struct _GtkSheetRange
{
- glong row0,col0; /* upper-left cell */
- glong rowi,coli; /* lower-right cell */
+ gint row0, col0; /* upper-left cell */
+ gint rowi, coli; /* lower-right cell */
};
struct _GtkSheetCellBorder
glong row, glong n_rows);
void (* columns_inserted) (GSheetModel *sheet_model,
- glong column, glong n_columns);
+ glong column, glong n_columns);
void (* columns_deleted) (GSheetModel *sheet_model,
- glong column, glong n_columns);
+ glong column, glong n_columns);
+
+
/* Virtual Table */
gchar * (* get_string) (const GSheetModel *sheet_model,
- glong row, glong column);
+ glong row, glong column);
gboolean (* set_string) (GSheetModel *sheet_model,
const gchar *s, glong row, glong column);
gboolean (* clear_datum) (GSheetModel *sheet_model,
glong row, glong column);
- gboolean (* is_visible) (const GSheetModel *sheet_model, glong row, glong column);
gboolean (* is_editable) (const GSheetModel *sheet_model, glong row, glong column);
- const GdkColor * (* get_foreground) (const GSheetModel *sheet_model,
- glong row, glong column);
+ GdkColor * (* get_foreground) (const GSheetModel *sheet_model,
+ glong row, glong column);
- const GdkColor * (* get_background) (const GSheetModel *sheet_model,
- glong row, glong column);
+ GdkColor * (* get_background) (const GSheetModel *sheet_model,
+ glong row, glong column);
const GtkJustification * (* get_justification) (const GSheetModel *sheet_model,
glong row, glong column);
- const PangoFontDescription * (* get_font_desc) (const GSheetModel *sheet_model,
- glong row, glong column);
-
- const GtkSheetCellBorder * (* get_cell_border) (const GSheetModel *sheet_model,
- glong row, glong column);
+ /* column related metadata */
+ gchar * (*get_column_title) (const GSheetModel *, gint col);
+ gchar * (*get_column_subtitle) (const GSheetModel *, gint col);
+ gboolean (*get_column_sensitivity) (const GSheetModel *, gint col);
+ GtkJustification (*get_column_justification) (const GSheetModel *mode, gint col);
+ const GtkSheetButton * (* get_button) (const GSheetModel *model, gint col);
glong (*get_column_count) (const GSheetModel *model);
- glong (*get_row_count) (const GSheetModel *model);
+ /* row related metadata */
+ gchar * (*get_row_title) (const GSheetModel *, gint row);
+ gchar * (*get_row_subtitle) (const GSheetModel *, gint row);
+ glong (*get_row_count) (const GSheetModel *model);
+ gboolean (*get_row_sensitivity) (const GSheetModel *, gint row);
};
GType g_sheet_model_get_type (void) G_GNUC_CONST;
-inline gchar * g_sheet_model_get_string (const GSheetModel *sheet_model,
- glong row, glong column);
+gchar * g_sheet_model_get_string (const GSheetModel *sheet_model,
+ glong row, glong column);
+
+gboolean g_sheet_model_set_string (GSheetModel *sheet_model,
+ const gchar *s,
+ glong row, glong column);
+
+gboolean g_sheet_model_datum_clear (GSheetModel *sheet_model,
+ glong row, glong column);
+
+
+void g_sheet_model_range_changed (GSheetModel *sheet_model,
+ glong row0, glong col0,
+ glong rowi, glong coli);
+
+void g_sheet_model_rows_deleted (GSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+void g_sheet_model_rows_inserted (GSheetModel *sheet_model,
+ glong row, glong n_rows);
+
+void g_sheet_model_columns_inserted (GSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+void g_sheet_model_columns_deleted (GSheetModel *sheet_model,
+ glong column, glong n_columns);
+
+
+gboolean g_sheet_model_is_editable (const GSheetModel *model,
+ glong row, glong column);
+
+gboolean g_sheet_model_is_visible
+ (const GSheetModel *model, glong row, glong column);
-inline gboolean g_sheet_model_set_string (GSheetModel *sheet_model,
- const gchar *s,
- glong row, glong column);
-inline gboolean g_sheet_model_datum_clear (GSheetModel *sheet_model,
- glong row, glong column);
+GdkColor *g_sheet_model_get_foreground
+ (const GSheetModel *model, glong row, glong column);
+GdkColor *g_sheet_model_get_background
+ (const GSheetModel *model, glong row, glong column);
-inline void g_sheet_model_range_changed (GSheetModel *sheet_model,
- glong row0, glong col0,
- glong rowi, glong coli);
+const GtkJustification *g_sheet_model_get_justification
+ (const GSheetModel *model, glong row, glong column);
-inline void g_sheet_model_rows_deleted (GSheetModel *sheet_model,
- glong row, glong n_rows);
+const GtkSheetCellBorder * g_sheet_model_get_cell_border
+ (const GSheetModel *model, glong row, glong column);
-inline void g_sheet_model_rows_inserted (GSheetModel *sheet_model,
- glong row, glong n_rows);
+gboolean g_sheet_model_free_strings (const GSheetModel *sheet_model);
-inline void g_sheet_model_columns_inserted (GSheetModel *sheet_model,
- glong column, glong n_columns);
+glong g_sheet_model_get_column_count (const GSheetModel *sheet_model);
-inline void g_sheet_model_columns_deleted (GSheetModel *sheet_model,
- glong column, glong n_columns);
+gint g_sheet_model_get_row_count (const GSheetModel *sheet_model);
+\f
-inline gboolean g_sheet_model_is_editable (const GSheetModel *model,
- glong row, glong column);
+gboolean g_sheet_model_get_column_sensitivity (const GSheetModel *model,
+ gint col);
-inline gboolean g_sheet_model_is_visible
- (const GSheetModel *model, glong row, glong column);
+gchar * g_sheet_model_get_column_subtitle (const GSheetModel *model,
+ gint col);
+GtkSheetButton * g_sheet_model_get_column_button (const GSheetModel *, gint);
-inline const GdkColor *g_sheet_model_get_foreground
- (const GSheetModel *model, glong row, glong column);
+GtkJustification g_sheet_model_get_column_justification (const GSheetModel *,
+ gint);
-inline const GdkColor *g_sheet_model_get_background
- (const GSheetModel *model, glong row, glong column);
+\f
+gboolean g_sheet_model_get_row_sensitivity (const GSheetModel *model,
+ gint row);
-inline const GtkJustification *g_sheet_model_get_justification
- (const GSheetModel *model, glong row, glong column);
+gchar * g_sheet_model_get_row_subtitle (const GSheetModel *model,
+ gint row);
-inline const PangoFontDescription *g_sheet_model_get_font_desc
- (const GSheetModel *model, glong row, glong column);
-inline const GtkSheetCellBorder * g_sheet_model_get_cell_border
- (const GSheetModel *model, glong row, glong column);
+GtkSheetButton * g_sheet_model_get_row_button (const GSheetModel *, gint);
-inline gboolean g_sheet_model_free_strings (const GSheetModel *sheet_model);
-inline glong g_sheet_model_get_column_count (const GSheetModel *sheet_model);
-inline gint g_sheet_model_get_row_count (const GSheetModel *sheet_model);
G_END_DECLS
+++ /dev/null
-#include <config.h>
-
-#include <glib-object.h>
-
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v) g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v) g_value_get_int (v)
-#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-#define g_marshal_value_peek_long(v) g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-#define g_marshal_value_peek_float(v) g_value_get_float (v)
-#define g_marshal_value_peek_double(v) g_value_get_double (v)
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v) g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v) g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- * Do not access GValues directly in your code. Instead, use the
- * g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_int
-#define g_marshal_value_peek_flags(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* BOOL:INT,INT,POINTER,POINTER (gtkextra-marshal.list:1) */
-void
-gtkextra_BOOLEAN__INT_INT_POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gpointer arg_3,
- gpointer arg_4,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 5);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- g_marshal_value_peek_pointer (param_values + 3),
- g_marshal_value_peek_pointer (param_values + 4),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:BOXED,POINTER (gtkextra-marshal.list:2) */
-void
-gtkextra_BOOLEAN__BOXED_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:BOXED,STRING (gtkextra-marshal.list:3) */
-void
-gtkextra_BOOLEAN__BOXED_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_STRING callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__BOXED_STRING) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_string (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:BOXED,BOXED (gtkextra-marshal.list:4) */
-void
-gtkextra_BOOLEAN__BOXED_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_BOXED) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_BOXED callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_boxed (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:BOXED,DOUBLE,DOUBLE (gtkextra-marshal.list:5) */
-void
-gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE) (gpointer data1,
- gpointer arg_1,
- gdouble arg_2,
- gdouble arg_3,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_double (param_values + 2),
- g_marshal_value_peek_double (param_values + 3),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:POINTER,POINTER (gtkextra-marshal.list:6) */
-void
-gtkextra_BOOLEAN__POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__POINTER_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:POINTER,BOXED (gtkextra-marshal.list:7) */
-void
-gtkextra_BOOLEAN__POINTER_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_BOXED) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__POINTER_BOXED callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__POINTER_BOXED) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
- g_marshal_value_peek_boxed (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:POINTER,STRING (gtkextra-marshal.list:8) */
-void
-gtkextra_BOOLEAN__POINTER_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_STRING) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__POINTER_STRING callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__POINTER_STRING) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
- g_marshal_value_peek_string (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:POINTER (gtkextra-marshal.list:9) */
-void
-gtkextra_BOOLEAN__POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 2);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:BOXED (gtkextra-marshal.list:10) */
-void
-gtkextra_BOOLEAN__BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer data1,
- gpointer arg_1,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 2);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOL:INT,INT (gtkextra-marshal.list:11) */
-void
-gtkextra_BOOLEAN__INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__INT_INT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__INT_INT) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* VOID:INT (gtkextra-marshal.list:12) */
-
-/* VOID:INT,STRING (gtkextra-marshal.list:13) */
-void
-gtkextra_VOID__INT_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_STRING) (gpointer data1,
- gint arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__INT_STRING callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_STRING) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_string (param_values + 2),
- data2);
-}
-
-/* VOID:BOXED (gtkextra-marshal.list:14) */
-
-/* VOID:VOID (gtkextra-marshal.list:15) */
-
-/* VOID:BOOL (gtkextra-marshal.list:16) */
-
-/* VOID:POINTER (gtkextra-marshal.list:17) */
-
-/* VOID:INT,INT (gtkextra-marshal.list:18) */
-void
-gtkextra_VOID__INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__INT_INT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- data2);
-}
-
-
-/* VOID:INT,INT,INT,INT (Added by JMD 1/1/2006) */
-void
-gtkextra_VOID__INT_INT_INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_INT_INT_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gint arg_3,
- gint arg_4,
- gpointer data2);
- register GMarshalFunc_VOID__INT_INT_INT_INT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 5);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- g_marshal_value_peek_int (param_values + 3),
- g_marshal_value_peek_int (param_values + 4),
- data2);
-}
-
-
-/* VOID:INT,POINTER (gtkextra-marshal.list:19) */
-void
-gtkextra_VOID__INT_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
- gint arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__INT_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- data2);
-}
-
-/* VOID:INT,BOXED (gtkextra-marshal.list:20) */
-void
-gtkextra_VOID__INT_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_BOXED) (gpointer data1,
- gint arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__INT_BOXED callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_BOXED) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_boxed (param_values + 2),
- data2);
-}
-
-/* VOID:POINTER,POINTER (gtkextra-marshal.list:21) */
-void
-gtkextra_VOID__POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__POINTER_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__POINTER_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- data2);
-}
-
-/* VOID:BOXED,POINTER (gtkextra-marshal.list:22) */
-void
-gtkextra_VOID__BOXED_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__BOXED_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__BOXED_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- data2);
-}
-
-/* VOID:BOXED,BOXED (gtkextra-marshal.list:23) */
-void
-gtkextra_VOID__BOXED_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__BOXED_BOXED) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__BOXED_BOXED callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_boxed (param_values + 2),
- data2);
-}
-
-/* VOID:OBJECT,OBJECT (gtkextra-marshal.list:24) */
-void
-gtkextra_VOID__OBJECT_OBJECT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__OBJECT_OBJECT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_object (param_values + 1),
- g_marshal_value_peek_object (param_values + 2),
- data2);
-}
-
-/* VOID:DOUBLE,DOUBLE,DOUBLE,DOUBLE (gtkextra-marshal.list:25) */
-void
-gtkextra_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE) (gpointer data1,
- gdouble arg_1,
- gdouble arg_2,
- gdouble arg_3,
- gdouble arg_4,
- gpointer data2);
- register GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 5);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_double (param_values + 1),
- g_marshal_value_peek_double (param_values + 2),
- g_marshal_value_peek_double (param_values + 3),
- g_marshal_value_peek_double (param_values + 4),
- data2);
-}
-
+++ /dev/null
-
-#ifndef __gtkextra_MARSHAL_H__
-#define __gtkextra_MARSHAL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* BOOL:INT,INT,POINTER,POINTER (gtkextra-marshal.list:1) */
-extern void gtkextra_BOOLEAN__INT_INT_POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__INT_INT_POINTER_POINTER gtkextra_BOOLEAN__INT_INT_POINTER_POINTER
-
-/* BOOL:BOXED,POINTER (gtkextra-marshal.list:2) */
-extern void gtkextra_BOOLEAN__BOXED_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__BOXED_POINTER gtkextra_BOOLEAN__BOXED_POINTER
-
-/* BOOL:BOXED,STRING (gtkextra-marshal.list:3) */
-extern void gtkextra_BOOLEAN__BOXED_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__BOXED_STRING gtkextra_BOOLEAN__BOXED_STRING
-
-/* BOOL:BOXED,BOXED (gtkextra-marshal.list:4) */
-extern void gtkextra_BOOLEAN__BOXED_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__BOXED_BOXED gtkextra_BOOLEAN__BOXED_BOXED
-
-/* BOOL:BOXED,DOUBLE,DOUBLE (gtkextra-marshal.list:5) */
-extern void gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__BOXED_DOUBLE_DOUBLE gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE
-
-/* BOOL:POINTER,POINTER (gtkextra-marshal.list:6) */
-extern void gtkextra_BOOLEAN__POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__POINTER_POINTER gtkextra_BOOLEAN__POINTER_POINTER
-
-/* BOOL:POINTER,BOXED (gtkextra-marshal.list:7) */
-extern void gtkextra_BOOLEAN__POINTER_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__POINTER_BOXED gtkextra_BOOLEAN__POINTER_BOXED
-
-/* BOOL:POINTER,STRING (gtkextra-marshal.list:8) */
-extern void gtkextra_BOOLEAN__POINTER_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__POINTER_STRING gtkextra_BOOLEAN__POINTER_STRING
-
-/* BOOL:POINTER (gtkextra-marshal.list:9) */
-extern void gtkextra_BOOLEAN__POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__POINTER gtkextra_BOOLEAN__POINTER
-
-/* BOOL:BOXED (gtkextra-marshal.list:10) */
-extern void gtkextra_BOOLEAN__BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__BOXED gtkextra_BOOLEAN__BOXED
-
-/* BOOL:INT,INT (gtkextra-marshal.list:11) */
-extern void gtkextra_BOOLEAN__INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-#define gtkextra_BOOL__INT_INT gtkextra_BOOLEAN__INT_INT
-
-/* VOID:INT (gtkextra-marshal.list:12) */
-#define gtkextra_VOID__INT g_cclosure_marshal_VOID__INT
-
-/* VOID:INT,STRING (gtkextra-marshal.list:13) */
-extern void gtkextra_VOID__INT_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:BOXED (gtkextra-marshal.list:14) */
-#define gtkextra_VOID__BOXED g_cclosure_marshal_VOID__BOXED
-
-/* VOID:VOID (gtkextra-marshal.list:15) */
-#define gtkextra_VOID__VOID g_cclosure_marshal_VOID__VOID
-
-/* VOID:BOOL (gtkextra-marshal.list:16) */
-#define gtkextra_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN
-#define gtkextra_VOID__BOOL gtkextra_VOID__BOOLEAN
-
-/* VOID:POINTER (gtkextra-marshal.list:17) */
-#define gtkextra_VOID__POINTER g_cclosure_marshal_VOID__POINTER
-
-/* VOID:INT,INT (gtkextra-marshal.list:18) */
-extern void gtkextra_VOID__INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:INT,INT,INT,INT (Added by JMD 1/1/26) */
-extern void gtkextra_VOID__INT_INT_INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-
-/* VOID:INT,POINTER (gtkextra-marshal.list:19) */
-extern void gtkextra_VOID__INT_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:INT,BOXED (gtkextra-marshal.list:20) */
-extern void gtkextra_VOID__INT_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:POINTER,POINTER (gtkextra-marshal.list:21) */
-extern void gtkextra_VOID__POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:BOXED,POINTER (gtkextra-marshal.list:22) */
-extern void gtkextra_VOID__BOXED_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:BOXED,BOXED (gtkextra-marshal.list:23) */
-extern void gtkextra_VOID__BOXED_BOXED (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:OBJECT,OBJECT (gtkextra-marshal.list:24) */
-extern void gtkextra_VOID__OBJECT_OBJECT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:DOUBLE,DOUBLE,DOUBLE,DOUBLE (gtkextra-marshal.list:25) */
-extern void gtkextra_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-G_END_DECLS
-
-#endif /* __gtkextra_MARSHAL_H__ */
-
*/
-#ifndef __GTK_EXTRA_SHEET_H__
-#define __GTK_EXTRA_SHEET_H__
+#ifndef GTK_EXTRA_SHEET_H__
+#define GTK_EXTRA_SHEET_H__
struct _GtkSheet ;
typedef struct _GtkSheet GtkSheet;
-struct _GtkSheetChild
-{
- GtkWidget *widget;
- gint x,y ;
- gboolean attached_to_cell;
- gboolean floating;
- gint row, col;
- guint16 xpadding;
- guint16 ypadding;
- gboolean xexpand;
- gboolean yexpand;
- gboolean xshrink;
- gboolean yshrink;
- gboolean xfill;
- gboolean yfill;
-};
-
-typedef struct _GtkSheetChild GtkSheetChild;
-
-
-
struct _GtkSheetButton
{
GtkStateType state;
gchar *label;
gboolean label_visible;
- GtkSheetChild *child;
GtkJustification justification;
};
-typedef struct _GtkSheetButton GtkSheetButton;
-
+struct _GtkSheetCell
+{
+ gint row;
+ gint col;
+};
+typedef struct _GtkSheetButton GtkSheetButton;
+typedef struct _GtkSheetCell GtkSheetCell;
-GtkSheetButton * gtk_sheet_button_new(void);
+GtkSheetButton * gtk_sheet_button_new (void);
-inline void gtk_sheet_button_free(GtkSheetButton *button);
+void gtk_sheet_button_free (GtkSheetButton *button);
-#endif /* __GTK_EXTRA_SHEET_H__ */
+#endif /* GTK_EXTRA_SHEET_H__ */
+++ /dev/null
-/* gtkextra
- * Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gtkextrafeatures.h"
-#include <gobject/gvaluecollector.h>
-
-const guint gtkextra_major_version = GTKEXTRA_MAJOR_VERSION;
-const guint gtkextra_minor_version = GTKEXTRA_MINOR_VERSION;
-const guint gtkextra_micro_version = GTKEXTRA_MICRO_VERSION;
-const guint gtkextra_binary_age = GTKEXTRA_BINARY_AGE;
-const guint gtkextra_interface_age = GTKEXTRA_INTERFACE_AGE;
-
-gchar *
-gtkextra_check_version (guint required_major,
- guint required_minor,
- guint required_micro)
-{
- if (required_major > GTKEXTRA_MAJOR_VERSION)
- return "GtkExtra version too old (major mismatch)";
- if (required_major < GTKEXTRA_MAJOR_VERSION)
- return "GtkExtra version too new (major mismatch)";
- if (required_minor > GTKEXTRA_MINOR_VERSION)
- return "GtkExtra version too old (minor mismatch)";
- if (required_minor < GTKEXTRA_MINOR_VERSION)
- return "GtkExtra version too new (minor mismatch)";
- if (required_micro < GTKEXTRA_MICRO_VERSION - GTKEXTRA_BINARY_AGE)
- return "GtkExtra version too new (micro mismatch)";
- if (required_micro > GTKEXTRA_MICRO_VERSION)
- return "GtkExtra version too old (micro mismatch)";
- return NULL;
-}
-
-/*
-void
-_gtkextra_signal_test(GtkObject *object, guint signal_id, gint arg1, gint arg2, gboolean *default_ret)
-{
- gboolean result;
- GValue ret = { 0, };
- GValue instance_and_param[3] = { { 0, }, {0, }, {0, } };
-
- g_value_init(instance_and_param + 0, GTK_OBJECT_TYPE(object));
- g_value_set_instance(instance_and_param + 0, G_OBJECT(object));
-
- g_value_init(instance_and_param + 1, G_TYPE_INT);
- g_value_set_int(instance_and_param + 1, arg1);
-
- g_value_init(instance_and_param + 2, G_TYPE_INT);
- g_value_set_int(instance_and_param + 2, arg2);
-
- g_value_init(&ret, G_TYPE_BOOLEAN);
- g_value_set_boolean(&ret, *default_ret);
-
- g_signal_emitv(instance_and_param, signal_id, 0, &ret);
- *default_ret = g_value_get_boolean(&ret);
-
- g_value_unset(instance_and_param + 0);
- g_value_unset(instance_and_param + 1);
- g_value_unset(instance_and_param + 2);
-}
-*/
-
-void
-_gtkextra_signal_emit(GtkObject *object, guint signal_id, ...)
-{
- gboolean *result;
- GValue ret = { 0, };
- GValue instance_and_params [10] = { {0, }, };
- va_list var_args;
- GSignalQuery query;
- gchar *error;
- int i;
-
- va_start (var_args, signal_id);
-
- g_value_init(instance_and_params + 0, GTK_OBJECT_TYPE(object));
- g_value_set_instance (instance_and_params + 0, G_OBJECT(object));
-
- g_signal_query(signal_id, &query);
-
- for (i = 0; i < query.n_params; i++)
- {
- gboolean static_scope = query.param_types[i]&~G_SIGNAL_TYPE_STATIC_SCOPE;
- g_value_init(instance_and_params + i + 1, query.param_types[i]);
-
-
- G_VALUE_COLLECT (instance_and_params + i + 1,
- var_args,
- static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
- &error);
-
- if (error)
- {
- g_warning ("%s: %s", G_STRLOC, error);
- g_free (error);
- while (i-- > 0)
- g_value_unset (instance_and_params + i);
-
- va_end (var_args);
- return;
- }
-
-
- }
-
- g_value_init(&ret, query.return_type);
- result = va_arg(var_args,gboolean *);
- g_value_set_boolean(&ret, *result);
- g_signal_emitv(instance_and_params, signal_id, 0, &ret);
- *result = g_value_get_boolean(&ret);
- g_value_unset (&ret);
-
- for (i = 0; i < query.n_params; i++)
- g_value_unset (instance_and_params + 1 + i);
- g_value_unset (instance_and_params + 0);
-
- va_end (var_args);
-}
+++ /dev/null
-/* gtkextra - set of widgets for gtk+
- * Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef GTK_EXTRA_FEATURES_H
-#define GTK_EXTRA_FEATURES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/* GtkExtra version.
- */
-
-#define GTKEXTRA_MAJOR_VERSION (2)
-#define GTKEXTRA_MINOR_VERSION (1)
-#define GTKEXTRA_MICRO_VERSION (1)
-#define GTKEXTRA_BINARY_AGE (0)
-#define GTKEXTRA_INTERFACE_AGE (0)
-#define GTKEXTRA_CHECK_VERSION(major,minor,micro) \
- (GTKEXTRA_MAJOR_VERSION > (major) || \
- (GTKEXTRA_MAJOR_VERSION == (major) && GTKEXTRA_MINOR_VERSION > (minor)) || \
- (GTKEXTRA_MAJOR_VERSION == (major) && GTKEXTRA_MINOR_VERSION == (minor) && \
- GTKEXTRA_MICRO_VERSION >= (micro)))
-
-
-extern const guint gtkextra_major_version;
-extern const guint gtkextra_minor_version;
-extern const guint gtkextra_micro_version;
-extern const guint gtkextra_binary_age;
-extern const guint gtkextra_interface_age;
-gchar* gtkextra_check_version (guint required_major,
- guint required_minor,
- guint required_micro);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* GTK_EXTRA_FEATURES_H */
+++ /dev/null
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <pango/pango.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include "gtkitementry.h"
-
-#define MIN_ENTRY_WIDTH 150
-#define DRAW_TIMEOUT 20
-#define INNER_BORDER 0
-
-/* Initial size of buffer, in bytes */
-#define MIN_SIZE 16
-
-/* Maximum size of text buffer, in bytes */
-#define MAX_SIZE G_MAXUSHORT
-
-typedef enum {
- CURSOR_STANDARD,
- CURSOR_DND
-} CursorType;
-
-/* GObject, GtkObject methods
- */
-static void gtk_item_entry_class_init (GtkItemEntryClass *klass);
-static void gtk_item_entry_init (GtkItemEntry *entry);
-static void gtk_item_entry_editable_init (GtkEditableClass *iface);
-
-/* GtkWidget methods
- */
-static void gtk_entry_realize (GtkWidget *widget);
-static void gtk_entry_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_entry_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gtk_entry_draw_frame (GtkWidget *widget);
-static gint gtk_entry_expose (GtkWidget *widget,
- GdkEventExpose *event);
-static void gtk_entry_grab_focus (GtkWidget *widget);
-static void gtk_entry_style_set (GtkWidget *widget,
- GtkStyle *previous_style);
-static void gtk_entry_direction_changed (GtkWidget *widget,
- GtkTextDirection previous_dir);
-static void gtk_entry_state_changed (GtkWidget *widget,
- GtkStateType previous_state);
-
-/* GtkEditable method implementations
- */
-static void gtk_entry_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position);
-static void gtk_entry_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-
-static void gtk_entry_real_set_position (GtkEditable *editable,
- gint position);
-static gint gtk_entry_get_position (GtkEditable *editable);
-
-/* Default signal handlers
- */
-static void gtk_entry_real_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position);
-static void gtk_entry_real_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-static void gtk_entry_move_cursor (GtkEntry *entry,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection);
-static void gtk_entry_insert_at_cursor (GtkEntry *entry,
- const gchar *str);
-static void gtk_entry_delete_from_cursor (GtkEntry *entry,
- GtkDeleteType type,
- gint count);
-
-/* IM Context Callbacks
- */
-static void gtk_entry_commit_cb (GtkIMContext *context,
- const gchar *str,
- GtkEntry *entry);
-static void gtk_entry_preedit_changed_cb (GtkIMContext *context,
- GtkEntry *entry);
-static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
- GtkEntry *entry);
-static gboolean gtk_entry_delete_surrounding_cb (GtkIMContext *context,
- gint offset,
- gint n_chars,
- GtkEntry *entry);
-
-/* Internal routines
- */
-static void gtk_entry_enter_text (GtkEntry *entry,
- const gchar *str);
-static void gtk_entry_set_positions (GtkEntry *entry,
- gint current_pos,
- gint selection_bound);
-static void gtk_entry_draw_text (GtkEntry *entry);
-static void gtk_entry_draw_cursor (GtkEntry *entry,
- CursorType type);
-static PangoLayout *gtk_entry_ensure_layout (GtkEntry *entry,
- gboolean include_preedit);
-static void gtk_entry_queue_draw (GtkEntry *entry);
-static void gtk_entry_reset_im_context (GtkEntry *entry);
-static void gtk_entry_recompute (GtkEntry *entry);
-static void gtk_entry_get_cursor_locations (GtkEntry *entry,
- CursorType type,
- gint *strong_x,
- gint *weak_x);
-static void gtk_entry_adjust_scroll (GtkEntry *entry);
-static gint gtk_entry_move_visually (GtkEntry *editable,
- gint start,
- gint count);
-static gint gtk_entry_move_logically (GtkEntry *entry,
- gint start,
- gint count);
-static gint gtk_entry_move_forward_word (GtkEntry *entry,
- gint start);
-static gint gtk_entry_move_backward_word (GtkEntry *entry,
- gint start);
-static void gtk_entry_delete_whitespace (GtkEntry *entry);
-static char * gtk_entry_get_public_chars (GtkEntry *entry,
- gint start,
- gint end);
-static void gtk_entry_update_primary_selection (GtkEntry *entry);
-static void gtk_entry_state_changed (GtkWidget *widget,
- GtkStateType previous_state);
-static void gtk_entry_check_cursor_blink (GtkEntry *entry);
-static void gtk_entry_pend_cursor_blink (GtkEntry *entry);
-static void get_text_area_size (GtkEntry *entry,
- gint *x,
- gint *y,
- gint *width,
- gint *height);
-static void get_widget_window_size (GtkEntry *entry,
- gint *x,
- gint *y,
- gint *width,
- gint *height);
-
-static GtkEntryClass *parent_class = NULL;
-
-GtkType
-gtk_item_entry_get_type (void)
-{
- static GtkType item_entry_type = 0;
-
- if (!item_entry_type)
- {
- static const GtkTypeInfo item_entry_info =
- {
- "GtkItemEntry",
- sizeof (GtkItemEntry),
- sizeof (GtkItemEntryClass),
- (GtkClassInitFunc) gtk_item_entry_class_init,
- (GtkObjectInitFunc) gtk_item_entry_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- static const GInterfaceInfo item_editable_info =
- {
- (GInterfaceInitFunc) gtk_item_entry_editable_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
-
- item_entry_type = gtk_type_unique (GTK_TYPE_ENTRY, &item_entry_info);
-
- g_type_add_interface_static (item_entry_type,
- GTK_TYPE_EDITABLE,
- &item_editable_info);
-
- }
-
- return item_entry_type;
-}
-
-static void
-gtk_item_entry_class_init (GtkItemEntryClass *class)
-{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- GtkEntryClass *entry_class;
-
- object_class = (GtkObjectClass*) class;
- widget_class = (GtkWidgetClass*) class;
- parent_class = gtk_type_class (GTK_TYPE_ENTRY);
- entry_class = (GtkEntryClass *) class;
-
- widget_class->realize = gtk_entry_realize;
- widget_class->size_request = gtk_entry_size_request;
- widget_class->size_allocate = gtk_entry_size_allocate;
- widget_class->expose_event = gtk_entry_expose;
- widget_class->grab_focus = gtk_entry_grab_focus;
- widget_class->style_set = gtk_entry_style_set;
- widget_class->direction_changed = gtk_entry_direction_changed;
- widget_class->state_changed = gtk_entry_state_changed;
-
- entry_class->move_cursor = gtk_entry_move_cursor;
- entry_class->insert_at_cursor = gtk_entry_insert_at_cursor;
- entry_class->delete_from_cursor = gtk_entry_delete_from_cursor;
-
-}
-
-static void
-gtk_item_entry_editable_init (GtkEditableClass *iface)
-{
- iface->do_insert_text = gtk_entry_insert_text;
- iface->do_delete_text = gtk_entry_delete_text;
- iface->insert_text = gtk_entry_real_insert_text;
- iface->delete_text = gtk_entry_real_delete_text;
- iface->set_position = gtk_entry_real_set_position;
- iface->get_position = gtk_entry_get_position;
-}
-
-static void
-gtk_item_entry_init (GtkItemEntry *entry)
-{
- entry->justification = GTK_JUSTIFY_LEFT;
- entry->text_max_size = 0;
- GTK_ENTRY(entry)->has_frame = FALSE;
-
- g_object_unref(G_OBJECT(GTK_ENTRY(entry)->im_context));
-
- GTK_ENTRY(entry)->im_context = gtk_im_multicontext_new ();
-
- g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "commit",
- G_CALLBACK (gtk_entry_commit_cb), entry);
- g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "preedit_changed",
- G_CALLBACK (gtk_entry_preedit_changed_cb), entry);
- g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "retrieve_surrounding",
- G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry);
- g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "delete_surrounding",
- G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
-
-}
-
-static void
-gtk_entry_realize (GtkWidget *widget)
-{
- GtkEntry *entry;
- GtkEditable *editable;
- GdkWindowAttr attributes;
- gint attributes_mask;
-
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (widget);
-
- attributes.window_type = GDK_WINDOW_CHILD;
-
- get_widget_window_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height);
-
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
- attributes.event_mask = gtk_widget_get_events (widget);
- attributes.event_mask |= (GDK_EXPOSURE_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON1_MOTION_MASK |
- GDK_BUTTON3_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_POINTER_MOTION_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
- widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
- gdk_window_set_user_data (widget->window, entry);
-
- get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height);
-
- attributes.cursor = gdk_cursor_new (GDK_XTERM);
- attributes_mask |= GDK_WA_CURSOR;
-
- entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
- gdk_window_set_user_data (entry->text_area, entry);
-
- gdk_cursor_unref (attributes.cursor);
-
- widget->style = gtk_style_attach (widget->style, widget->window);
-
- gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE(widget)]);
- gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]);
-
- gdk_window_show (entry->text_area);
-
- gtk_im_context_set_client_window (entry->im_context, entry->text_area);
-
- gtk_entry_adjust_scroll (entry);
-}
-
-static void
-get_borders (GtkEntry *entry,
- gint *xborder,
- gint *yborder)
-{
- GtkWidget *widget = GTK_WIDGET (entry);
- gint focus_width;
- gboolean interior_focus;
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- NULL);
-
- if (entry->has_frame)
- {
- *xborder = widget->style->xthickness;
- *yborder = widget->style->ythickness;
- }
- else
- {
- *xborder = 0;
- *yborder = 0;
- }
-
- if (!interior_focus)
- {
- *xborder += focus_width;
- *yborder += focus_width;
- }
-
-}
-
-static void
-gtk_entry_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
- PangoFontMetrics *metrics;
- gint xborder, yborder;
- PangoContext *context;
-
- context = gtk_widget_get_pango_context (widget);
- metrics = pango_context_get_metrics (context,
- widget->style->font_desc,
- pango_context_get_language (context));
-
- entry->ascent = pango_font_metrics_get_ascent (metrics);
- entry->descent = pango_font_metrics_get_descent (metrics);
-
- get_borders (entry, &xborder, &yborder);
-
- xborder += INNER_BORDER;
- yborder += INNER_BORDER;
-
- if (entry->width_chars < 0)
- requisition->width = MIN_ENTRY_WIDTH + xborder * 2;
- else
- {
- gint char_width = pango_font_metrics_get_approximate_char_width (metrics);
- requisition->width = PANGO_PIXELS (char_width) * entry->width_chars + xborder * 2;
- }
-
- requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2;
-
- pango_font_metrics_unref (metrics);
-}
-
-static void
-get_text_area_size (GtkEntry *entry,
- gint *x,
- gint *y,
- gint *width,
- gint *height)
-{
- gint xborder, yborder;
- GtkRequisition requisition;
- GtkWidget *widget = GTK_WIDGET (entry);
-
- gtk_widget_get_child_requisition (widget, &requisition);
-
- get_borders (entry, &xborder, &yborder);
-
- if (x)
- *x = xborder;
-
- if (y)
- *y = yborder;
-
- if (width)
- *width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
-
- if (height)
- *height = requisition.height - yborder * 2;
-}
-
-static void
-get_widget_window_size (GtkEntry *entry,
- gint *x,
- gint *y,
- gint *width,
- gint *height)
-{
- GtkRequisition requisition;
- GtkWidget *widget = GTK_WIDGET (entry);
-
- gtk_widget_get_child_requisition (widget, &requisition);
-
- if (x)
- *x = widget->allocation.x;
-
- if (y)
- {
- if (entry->is_cell_renderer)
- *y = widget->allocation.y;
- else
- *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
- }
-
- if (width)
- *width = widget->allocation.width;
-
- if (height)
- {
- if (entry->is_cell_renderer)
- *height = widget->allocation.height;
- else
- *height = requisition.height;
- }
-}
-
-static void
-gtk_entry_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
- GtkItemEntry *ientry = GTK_ITEM_ENTRY (widget);
-
- if(ientry->text_max_size > 0)
- allocation->width = MIN(ientry->text_max_size, allocation->width);
-
- widget->allocation = *allocation;
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- /* We call gtk_widget_get_child_requisition, since we want (for
- * backwards compatibility reasons) the realization here to
- * be affected by the usize of the entry, if set
- */
- gint x, y, width, height;
-
- get_widget_window_size (entry, &x, &y, &width, &height);
-
- gdk_window_move_resize (widget->window,
- allocation->x, allocation->y, allocation->width, allocation->height);
-
- get_text_area_size (entry, &x, &y, &width, &height);
-
- gdk_window_move_resize (entry->text_area,
- 0, allocation->height - height, allocation->width, height);
-
- gtk_entry_recompute (entry);
- }
-}
-
-static void
-gtk_entry_draw_frame (GtkWidget *widget)
-{
-}
-
-static gint
-gtk_entry_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
-
- if (widget->window == event->window)
- gtk_entry_draw_frame (widget);
- else if (entry->text_area == event->window)
- {
- gint area_width, area_height;
-
- get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
-
- gdk_draw_rectangle (entry->text_area,
- widget->style->bg_gc[GTK_WIDGET_STATE(widget)],
- TRUE,
- 0, 0, area_width, area_height);
-
- if ((entry->visible || entry->invisible_char != 0) &&
- GTK_WIDGET_HAS_FOCUS (widget) &&
- entry->selection_bound == entry->current_pos && entry->cursor_visible)
- gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD);
-
- if (entry->dnd_position != -1)
- gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_DND);
-
- gtk_entry_draw_text (GTK_ENTRY (widget));
- }
-
- return FALSE;
-}
-
-static void
-gtk_entry_grab_focus (GtkWidget *widget)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
- gboolean select_on_focus;
-
- GTK_WIDGET_CLASS (parent_class)->grab_focus (widget);
-
- g_object_get (G_OBJECT (gtk_settings_get_default ()),
- "gtk-entry-select-on-focus",
- &select_on_focus,
- NULL);
-
- if (select_on_focus && entry->editable && !entry->in_click)
- gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
-}
-
-static void
-gtk_entry_direction_changed (GtkWidget *widget,
- GtkTextDirection previous_dir)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
-
- gtk_entry_recompute (entry);
-
- GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
-}
-
-static void
-gtk_entry_state_changed (GtkWidget *widget,
- GtkStateType previous_state)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE (widget)]);
- gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]);
- }
-
- if (!GTK_WIDGET_IS_SENSITIVE (widget))
- {
- /* Clear any selection */
- gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos);
- }
-
- gtk_widget_queue_clear (widget);
-}
-
-/* GtkEditable method implementations
- */
-static void
-gtk_entry_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position)
-{
- GtkEntry *entry = GTK_ENTRY (editable);
- gchar buf[64];
- gchar *text;
-
- if (*position < 0 || *position > entry->text_length)
- *position = entry->text_length;
-
- g_object_ref (G_OBJECT (editable));
-
- if (new_text_length <= 63)
- text = buf;
- else
- text = g_new (gchar, new_text_length + 1);
-
- text[new_text_length] = '\0';
- strncpy (text, new_text, new_text_length);
-
- g_signal_emit_by_name (editable, "insert_text", text, new_text_length, position);
-
- if (new_text_length > 63)
- g_free (text);
-
- g_object_unref (G_OBJECT (editable));
-}
-
-static void
-gtk_entry_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry = GTK_ENTRY (editable);
-
- if (end_pos < 0 || end_pos > entry->text_length)
- end_pos = entry->text_length;
- if (start_pos < 0)
- start_pos = 0;
- if (start_pos > end_pos)
- start_pos = end_pos;
-
- g_object_ref (G_OBJECT (editable));
-
- g_signal_emit_by_name (editable, "delete_text", start_pos, end_pos);
-
- g_object_unref (G_OBJECT (editable));
-}
-
-static void
-gtk_entry_style_set (GtkWidget *widget,
- GtkStyle *previous_style)
-{
- GtkEntry *entry = GTK_ENTRY (widget);
-
- if (previous_style && GTK_WIDGET_REALIZED (widget))
- {
- gtk_entry_recompute (entry);
-
- gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE(widget)]);
- gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]);
- }
-}
-
-static void
-gtk_entry_real_set_position (GtkEditable *editable,
- gint position)
-{
- GtkEntry *entry = GTK_ENTRY (editable);
-
- if (position < 0 || position > entry->text_length)
- position = entry->text_length;
-
- if (position != entry->current_pos ||
- position != entry->selection_bound)
- {
- gtk_entry_reset_im_context (entry);
- gtk_entry_set_positions (entry, position, position);
- }
-}
-
-static gint
-gtk_entry_get_position (GtkEditable *editable)
-{
- return GTK_ENTRY (editable)->current_pos;
-}
-
-
-/* Default signal handlers
- */
-static void
-gtk_entry_real_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position)
-{
- gint index;
- gint n_chars;
-
- GtkEntry *entry = GTK_ENTRY (editable);
-
- if (new_text_length < 0)
- new_text_length = strlen (new_text);
-
- n_chars = g_utf8_strlen (new_text, new_text_length);
- if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length)
- {
- gdk_beep ();
- n_chars = entry->text_max_length - entry->text_length;
- new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text;
- }
-
- if (new_text_length + entry->n_bytes + 1 > entry->text_size)
- {
- while (new_text_length + entry->n_bytes + 1 > entry->text_size)
- {
- if (entry->text_size == 0)
- entry->text_size = MIN_SIZE;
- else
- {
- if (2 * (guint)entry->text_size < MAX_SIZE &&
- 2 * (guint)entry->text_size > entry->text_size)
- entry->text_size *= 2;
- else
- {
- entry->text_size = MAX_SIZE;
- if (new_text_length > (gint)entry->text_size - (gint)entry->n_bytes - 1)
- {
- new_text_length = (gint)entry->text_size - (gint)entry->n_bytes - 1;
- new_text_length = g_utf8_find_prev_char (new_text, new_text + new_text_length + 1) - new_text;
- n_chars = g_utf8_strlen (new_text, new_text_length);
- }
- break;
- }
- }
- }
-
- entry->text = g_realloc (entry->text, entry->text_size);
- }
-
- index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text;
-
- g_memmove (entry->text + index + new_text_length, entry->text + index, entry->n_bytes - index);
- memcpy (entry->text + index, new_text, new_text_length);
-
- entry->n_bytes += new_text_length;
- entry->text_length += n_chars;
-
- /* NUL terminate for safety and convenience */
- entry->text[entry->n_bytes] = '\0';
-
- if (entry->current_pos > *position)
- entry->current_pos += n_chars;
-
- if (entry->selection_bound > *position)
- entry->selection_bound += n_chars;
-
- *position += n_chars;
-
- gtk_entry_recompute (entry);
-
- g_signal_emit_by_name (editable, "changed");
- g_object_notify (G_OBJECT (editable), "text");
-}
-
-static void
-gtk_entry_real_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry = GTK_ENTRY (editable);
-
- if (start_pos < 0)
- start_pos = 0;
- if (end_pos < 0 || end_pos > entry->text_length)
- end_pos = entry->text_length;
-
- if (start_pos < end_pos)
- {
- gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
- gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
-
- g_memmove (entry->text + start_index, entry->text + end_index, entry->n_bytes + 1 - end_index);
- entry->text_length -= (end_pos - start_pos);
- entry->n_bytes -= (end_index - start_index);
-
- if (entry->current_pos > start_pos)
- entry->current_pos -= MIN (entry->current_pos, end_pos) - start_pos;
-
- if (entry->selection_bound > start_pos)
- entry->selection_bound -= MIN (entry->selection_bound, end_pos) - start_pos;
- /* We might have deleted the selection
- */
- gtk_entry_update_primary_selection (entry);
-
- gtk_entry_recompute (entry);
-
- g_signal_emit_by_name (editable, "changed");
- g_object_notify (G_OBJECT (editable), "text");
- }
-}
-
-/* Compute the X position for an offset that corresponds to the "more important
- * cursor position for that offset. We use this when trying to guess to which
- * end of the selection we should go to when the user hits the left or
- * right arrow key.
- */
-static gint
-get_better_cursor_x (GtkEntry *entry,
- gint offset)
-{
- GtkTextDirection keymap_direction =
- (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ?
- GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
- GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry));
- gboolean split_cursor;
-
- PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
- gint index = g_utf8_offset_to_pointer (entry->text, offset) - entry->text;
-
- PangoRectangle strong_pos, weak_pos;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)),
- "gtk-split-cursor", &split_cursor,
- NULL);
-
- pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
-
- if (split_cursor)
- return strong_pos.x / PANGO_SCALE;
- else
- return (keymap_direction == widget_direction) ? strong_pos.x / PANGO_SCALE : weak_pos.x / PANGO_SCALE;
-}
-
-static void
-gtk_entry_move_cursor (GtkEntry *entry,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection)
-{
- gint new_pos = entry->current_pos;
-
- gtk_entry_reset_im_context (entry);
-
- if (entry->current_pos != entry->selection_bound && !extend_selection)
- {
- /* If we have a current selection and aren't extending it, move to the
- * start/or end of the selection as appropriate
- */
- switch (step)
- {
- case GTK_MOVEMENT_VISUAL_POSITIONS:
- {
- gint current_x = get_better_cursor_x (entry, entry->current_pos);
- gint bound_x = get_better_cursor_x (entry, entry->selection_bound);
-
- if (count < 0)
- new_pos = current_x < bound_x ? entry->current_pos : entry->selection_bound;
- else
- new_pos = current_x > bound_x ? entry->current_pos : entry->selection_bound;
-
- break;
- }
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- case GTK_MOVEMENT_WORDS:
- if (count < 0)
- new_pos = MIN (entry->current_pos, entry->selection_bound);
- else
- new_pos = MAX (entry->current_pos, entry->selection_bound);
- break;
- case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
- case GTK_MOVEMENT_PARAGRAPH_ENDS:
- case GTK_MOVEMENT_BUFFER_ENDS:
- new_pos = count < 0 ? 0 : entry->text_length;
- break;
- case GTK_MOVEMENT_DISPLAY_LINES:
- case GTK_MOVEMENT_PARAGRAPHS:
- case GTK_MOVEMENT_PAGES:
- break;
- default:
- break;
- }
- }
- else
- {
- switch (step)
- {
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- new_pos = gtk_entry_move_logically (entry, new_pos, count);
- break;
- case GTK_MOVEMENT_VISUAL_POSITIONS:
- new_pos = gtk_entry_move_visually (entry, new_pos, count);
- break;
- case GTK_MOVEMENT_WORDS:
- while (count > 0)
- {
- new_pos = gtk_entry_move_forward_word (entry, new_pos);
- count--;
- }
- while (count < 0)
- {
- new_pos = gtk_entry_move_backward_word (entry, new_pos);
- count++;
- }
- break;
- case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
- case GTK_MOVEMENT_PARAGRAPH_ENDS:
- case GTK_MOVEMENT_BUFFER_ENDS:
- new_pos = count < 0 ? 0 : entry->text_length;
- break;
- case GTK_MOVEMENT_DISPLAY_LINES:
- case GTK_MOVEMENT_PARAGRAPHS:
- case GTK_MOVEMENT_PAGES:
- break;
- default:
- break;
- }
- }
-
- if (extend_selection)
- gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos);
- else
- gtk_editable_set_position (GTK_EDITABLE (entry), new_pos);
-
- gtk_entry_pend_cursor_blink (entry);
-}
-
-static void
-gtk_entry_insert_at_cursor (GtkEntry *entry,
- const gchar *str)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint pos = entry->current_pos;
-
- if (entry->editable)
- {
- gtk_entry_reset_im_context (entry);
-
- gtk_editable_insert_text (editable, str, -1, &pos);
- gtk_editable_set_position (editable, pos);
- }
-}
-
-static void
-gtk_entry_delete_from_cursor (GtkEntry *entry,
- GtkDeleteType type,
- gint count)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint start_pos = entry->current_pos;
- gint end_pos = entry->current_pos;
-
- gtk_entry_reset_im_context (entry);
-
- if (!entry->editable)
- return;
-
- if (entry->selection_bound != entry->current_pos)
- {
- gtk_editable_delete_selection (editable);
- return;
- }
-
- switch (type)
- {
- case GTK_DELETE_CHARS:
- end_pos = gtk_entry_move_logically (entry, entry->current_pos, count);
- gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos));
- break;
- case GTK_DELETE_WORDS:
- if (count < 0)
- {
- /* Move to end of current word, or if not on a word, end of previous word */
- end_pos = gtk_entry_move_backward_word (entry, end_pos);
- end_pos = gtk_entry_move_forward_word (entry, end_pos);
- }
- else if (count > 0)
- {
- /* Move to beginning of current word, or if not on a word, begining of next word */
- start_pos = gtk_entry_move_forward_word (entry, start_pos);
- start_pos = gtk_entry_move_backward_word (entry, start_pos);
- }
-
- /* Fall through */
- case GTK_DELETE_WORD_ENDS:
- while (count < 0)
- {
- start_pos = gtk_entry_move_backward_word (entry, start_pos);
- count++;
- }
- while (count > 0)
- {
- end_pos = gtk_entry_move_forward_word (entry, end_pos);
- count--;
- }
- gtk_editable_delete_text (editable, start_pos, end_pos);
- break;
- case GTK_DELETE_DISPLAY_LINE_ENDS:
- case GTK_DELETE_PARAGRAPH_ENDS:
- if (count < 0)
- gtk_editable_delete_text (editable, 0, entry->current_pos);
- else
- gtk_editable_delete_text (editable, entry->current_pos, -1);
- break;
- case GTK_DELETE_DISPLAY_LINES:
- case GTK_DELETE_PARAGRAPHS:
- gtk_editable_delete_text (editable, 0, -1);
- break;
- case GTK_DELETE_WHITESPACE:
- gtk_entry_delete_whitespace (entry);
- break;
- }
-
- gtk_entry_pend_cursor_blink (entry);
-}
-
-/* IM Context Callbacks
- */
-
-static void
-gtk_entry_commit_cb (GtkIMContext *context,
- const gchar *str,
- GtkEntry *entry)
-{
- gtk_entry_enter_text (entry, str);
-}
-
-static void
-gtk_entry_preedit_changed_cb (GtkIMContext *context,
- GtkEntry *entry)
-{
- gchar *preedit_string;
- gint cursor_pos;
-
- gtk_im_context_get_preedit_string (entry->im_context,
- &preedit_string, NULL,
- &cursor_pos);
- entry->preedit_length = strlen (preedit_string);
- cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
- entry->preedit_cursor = cursor_pos;
- g_free (preedit_string);
-
- gtk_entry_recompute (entry);
-}
-
-static gboolean
-gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
- GtkEntry *entry)
-{
- gtk_im_context_set_surrounding (context,
- entry->text,
- entry->n_bytes,
- g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text);
-
- return TRUE;
-}
-
-static gboolean
-gtk_entry_delete_surrounding_cb (GtkIMContext *slave,
- gint offset,
- gint n_chars,
- GtkEntry *entry)
-{
- gtk_editable_delete_text (GTK_EDITABLE (entry),
- entry->current_pos + offset,
- entry->current_pos + offset + n_chars);
-
- return TRUE;
-}
-
-
-/* Internal functions
- */
-
-/* Used for im_commit_cb and inserting Unicode chars */
-static void
-gtk_entry_enter_text (GtkEntry *entry,
- const gchar *str)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint tmp_pos;
-
- if (gtk_editable_get_selection_bounds (editable, NULL, NULL))
- gtk_editable_delete_selection (editable);
- else
- {
- if (entry->overwrite_mode)
- gtk_entry_delete_from_cursor (entry, GTK_DELETE_CHARS, 1);
- }
-
- tmp_pos = entry->current_pos;
- gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
- gtk_editable_set_position (editable, tmp_pos);
-}
-
-/* All changes to entry->current_pos and entry->selection_bound
- * should go through this function.
- */
-static void
-gtk_entry_set_positions (GtkEntry *entry,
- gint current_pos,
- gint selection_bound)
-{
- gboolean changed = FALSE;
-
- g_object_freeze_notify (G_OBJECT (entry));
-
- if (current_pos != -1 &&
- entry->current_pos != current_pos)
- {
- entry->current_pos = current_pos;
- changed = TRUE;
-
- g_object_notify (G_OBJECT (entry), "cursor_position");
- }
-
- if (selection_bound != -1 &&
- entry->selection_bound != selection_bound)
- {
- entry->selection_bound = selection_bound;
- changed = TRUE;
-
- g_object_notify (G_OBJECT (entry), "selection_bound");
- }
-
- g_object_thaw_notify (G_OBJECT (entry));
-
- if (changed)
- gtk_entry_recompute (entry);
-}
-
-static void
-gtk_entry_reset_layout (GtkEntry *entry)
-{
- if (entry->cached_layout)
- {
- g_object_unref (G_OBJECT (entry->cached_layout));
- entry->cached_layout = NULL;
- }
-}
-
-static void
-update_im_cursor_location (GtkEntry *entry)
-{
- GdkRectangle area;
- gint strong_x;
- gint strong_xoffset;
- gint x, y, area_width, area_height;
-
- gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL)
-;
- get_text_area_size (entry, &x, &y, &area_width, &area_height);
-
- strong_xoffset = strong_x - entry->scroll_offset;
- if (strong_xoffset < 0)
- {
- strong_xoffset = 0;
- }
- else if (strong_xoffset > area_width)
- {
- strong_xoffset = area_width;
- }
- area.x = x + strong_xoffset;
- area.y = y + area_height;
- area.width = area_width;
- area.height = area_height;
-
- gtk_im_context_set_cursor_location (entry->im_context, &area);
-}
-
-static gboolean
-recompute_idle_func (gpointer data)
-{
- GtkEntry *entry;
-
- GDK_THREADS_ENTER ();
-
- entry = GTK_ENTRY (data);
-
- gtk_entry_adjust_scroll (entry);
- gtk_entry_queue_draw (entry);
-
- entry->recompute_idle = FALSE;
-
- update_im_cursor_location (entry);
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
-static void
-gtk_entry_recompute (GtkEntry *entry)
-{
- gtk_entry_reset_layout (entry);
- gtk_entry_check_cursor_blink (entry);
-
-
- if (!entry->recompute_idle)
- {
- entry->recompute_idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */
- recompute_idle_func, entry, NULL);
- }
-}
-
-static void
-append_char (GString *str,
- gunichar ch,
- gint count)
-{
- gint i;
- gint char_len;
- gchar buf[7];
-
- char_len = g_unichar_to_utf8 (ch, buf);
-
- i = 0;
- while (i < count)
- {
- g_string_append_len (str, buf, char_len);
- ++i;
- }
-}
-
-static PangoLayout *
-gtk_entry_create_layout (GtkEntry *entry,
- gboolean include_preedit)
-{
- PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (entry), NULL);
- PangoAttrList *tmp_attrs = pango_attr_list_new ();
-
- gchar *preedit_string = NULL;
- gint preedit_length = 0;
- PangoAttrList *preedit_attrs = NULL;
-
- pango_layout_set_single_paragraph_mode (layout, TRUE);
-
- if (include_preedit)
- {
- gtk_im_context_get_preedit_string (entry->im_context,
- &preedit_string, &preedit_attrs, NULL);
- preedit_length = entry->preedit_length;
- }
-
- if (preedit_length)
- {
- GString *tmp_string = g_string_new (NULL);
-
- gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text;
-
- if (entry->visible)
- {
- g_string_prepend_len (tmp_string, entry->text, entry->n_bytes);
- g_string_insert (tmp_string, cursor_index, preedit_string);
- }
- else
- {
- gint ch_len;
- gint preedit_len_chars;
- gunichar invisible_char;
-
- ch_len = g_utf8_strlen (entry->text, entry->n_bytes);
- preedit_len_chars = g_utf8_strlen (preedit_string, -1);
- ch_len += preedit_len_chars;
-
- if (entry->invisible_char != 0)
- invisible_char = entry->invisible_char;
- else
- invisible_char = ' '; /* just pick a char */
-
- append_char (tmp_string, invisible_char, ch_len);
-
- /* Fix cursor index to point to invisible char corresponding
- * to the preedit, fix preedit_length to be the length of
- * the invisible chars representing the preedit
- */
- cursor_index =
- g_utf8_offset_to_pointer (tmp_string->str, entry->current_pos) -
- tmp_string->str;
- preedit_length =
- preedit_len_chars *
- g_unichar_to_utf8 (invisible_char, NULL);
- }
-
- pango_layout_set_text (layout, tmp_string->str, tmp_string->len);
-
- pango_attr_list_splice (tmp_attrs, preedit_attrs,
- cursor_index, preedit_length);
-
- g_string_free (tmp_string, TRUE);
- }
- else
- {
- if (entry->visible)
- {
- pango_layout_set_text (layout, entry->text, entry->n_bytes);
- }
- else
- {
- GString *str = g_string_new (NULL);
- gunichar invisible_char;
-
- if (entry->invisible_char != 0)
- invisible_char = entry->invisible_char;
- else
- invisible_char = ' '; /* just pick a char */
-
- append_char (str, invisible_char, entry->text_length);
- pango_layout_set_text (layout, str->str, str->len);
- g_string_free (str, TRUE);
- }
- }
-
- pango_layout_set_attributes (layout, tmp_attrs);
-
- if (preedit_string)
- g_free (preedit_string);
- if (preedit_attrs)
- pango_attr_list_unref (preedit_attrs);
-
- pango_attr_list_unref (tmp_attrs);
-
- return layout;
-}
-
-static PangoLayout *
-gtk_entry_ensure_layout (GtkEntry *entry,
- gboolean include_preedit)
-{
- if (entry->preedit_length > 0 &&
- !include_preedit != !entry->cache_includes_preedit)
- gtk_entry_reset_layout (entry);
-
- if (!entry->cached_layout)
- {
- entry->cached_layout = gtk_entry_create_layout (entry, include_preedit);
- entry->cache_includes_preedit = include_preedit;
- }
-
- return entry->cached_layout;
-}
-
-static void
-get_layout_position (GtkEntry *entry,
- gint *x,
- gint *y)
-{
- PangoLayout *layout;
- PangoRectangle logical_rect;
- gint area_width, area_height;
- gint y_pos;
- PangoLayoutLine *line;
-
- layout = gtk_entry_ensure_layout (entry, TRUE);
-
- get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
-
- area_height = PANGO_SCALE * (area_height);
-
- line = pango_layout_get_lines (layout)->data;
- pango_layout_line_get_extents (line, NULL, &logical_rect);
-
- /* Align primarily for locale's ascent/descent */
-
- y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
- entry->ascent + logical_rect.y);
-
-
- /* Now see if we need to adjust to fit in actual drawn string */
-
- if (logical_rect.height > area_height)
- y_pos = (area_height - logical_rect.height) / 2;
- else if (y_pos < 0)
- y_pos = 0;
- else if (y_pos + logical_rect.height > area_height)
- y_pos = area_height - logical_rect.height;
-
- y_pos = y_pos / PANGO_SCALE;
-
- if (x)
- *x = - entry->scroll_offset;
-
- if (y)
- *y = y_pos;
-}
-
-static void
-gtk_entry_draw_text (GtkEntry *entry)
-{
- GtkWidget *widget;
- PangoLayoutLine *line;
-
- if (!entry->visible && entry->invisible_char == 0)
- return;
-
- if (GTK_WIDGET_DRAWABLE (entry))
- {
- PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
- gint area_width, area_height;
-
- gint x, y;
- gint start_pos, end_pos;
-
- widget = GTK_WIDGET (entry);
-
- get_layout_position (entry, &x, &y);
-
- get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
-
-
- gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
- x, y,
- layout);
-
-
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
- {
- gint *ranges;
- gint n_ranges, i;
- PangoRectangle logical_rect;
- const gchar *text = pango_layout_get_text (layout);
- gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
- gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
- GdkRegion *clip_region = gdk_region_new ();
- GdkGC *text_gc;
- GdkGC *selection_gc;
-
- line = pango_layout_get_lines (layout)->data;
-
- pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
-
- pango_layout_get_extents (layout, NULL, &logical_rect);
-
- if (GTK_WIDGET_HAS_FOCUS (entry))
- {
- selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
- text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
- }
- else
- {
- selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
- text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
- }
-
- for (i=0; i < n_ranges; i++)
- {
- GdkRectangle rect;
-
- rect.x = INNER_BORDER - entry->scroll_offset + ranges[2*i] / PANGO_SCALE;
- rect.y = y;
- rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
- rect.height = logical_rect.height / PANGO_SCALE;
-
- gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
- rect.x, rect.y, rect.width, rect.height);
-
- gdk_region_union_with_rect (clip_region, &rect);
- }
-
- gdk_gc_set_clip_region (text_gc, clip_region);
- gdk_draw_layout (entry->text_area, text_gc,
- x, y,
- layout);
- gdk_gc_set_clip_region (text_gc, NULL);
-
- gdk_region_destroy (clip_region);
- g_free (ranges);
- }
- }
-}
-
-/*
- * From _gtk_get_insertion_cursor_gc
- */
-
-typedef struct _CursorInfo CursorInfo;
-
-struct _CursorInfo
-{
- GType for_type;
- GdkGC *primary_gc;
- GdkGC *secondary_gc;
-};
-
-static GdkGC *
-make_cursor_gc (GtkWidget *widget,
- const gchar *property_name,
- GdkColor *fallback)
-{
- GdkGCValues gc_values;
- GdkGCValuesMask gc_values_mask;
- GdkColor *cursor_color;
-
- gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
-
- gc_values_mask = GDK_GC_FOREGROUND;
- if (cursor_color)
- {
- gc_values.foreground = *cursor_color;
- gdk_color_free (cursor_color);
- }
- else
- gc_values.foreground = *fallback;
-
- gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
- return gtk_gc_get (widget->style->depth, widget->style->colormap,
- &gc_values, gc_values_mask);
-}
-
-static GdkGC *
-_gtkextra_get_insertion_cursor_gc (GtkWidget *widget,
- gboolean is_primary)
-{
- CursorInfo *cursor_info;
-
- cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
- if (!cursor_info)
- {
- cursor_info = g_new (CursorInfo, 1);
- g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
- cursor_info->primary_gc = NULL;
- cursor_info->secondary_gc = NULL;
- cursor_info->for_type = G_TYPE_INVALID;
- }
-
- /* We have to keep track of the type because gtk_widget_style_get()
- * can return different results when called on the same property and
- * same style but for different widgets. :-(. That is,
- * GtkEntry::cursor-color = "red" in a style will modify the cursor
- * color for entries but not for text view.
- */
- if (cursor_info->for_type != G_OBJECT_TYPE (widget))
- {
- cursor_info->for_type = G_OBJECT_TYPE (widget);
- if (cursor_info->primary_gc)
- {
- gtk_gc_release (cursor_info->primary_gc);
- cursor_info->primary_gc = NULL;
- }
- if (cursor_info->secondary_gc)
- {
- gtk_gc_release (cursor_info->secondary_gc);
- cursor_info->secondary_gc = NULL;
- }
- }
-
- if (is_primary)
- {
- if (!cursor_info->primary_gc)
- cursor_info->primary_gc = make_cursor_gc (widget,
- "cursor-color",
- &widget->style->black);
-
- return g_object_ref (cursor_info->primary_gc);
- }
- else
- {
- static GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
-
- if (!cursor_info->secondary_gc)
- cursor_info->secondary_gc = make_cursor_gc (widget,
- "secondary-cursor-color",
- &gray);
-
- return g_object_ref (cursor_info->secondary_gc);
- }
-}
-
-/*
- * From _gtk_draw_insertion_cursor
- */
-static void
-_gtkextra_draw_insertion_cursor (GtkWidget *widget,
- GdkDrawable *drawable,
- GdkGC *gc,
- GdkRectangle *location,
- GtkTextDirection direction,
- gboolean draw_arrow)
-{
- gint stem_width;
- gint arrow_width;
- gint x, y;
- gint i;
- gfloat cursor_aspect_ratio;
- gint offset;
-
- g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
-
- gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
-
- stem_width = location->height * cursor_aspect_ratio + 1;
- arrow_width = stem_width + 1;
-
- /* put (stem_width % 2) on the proper side of the cursor */
- if (direction == GTK_TEXT_DIR_LTR)
- offset = stem_width / 2;
- else
- offset = stem_width - stem_width / 2;
-
- for (i = 0; i < stem_width; i++)
- gdk_draw_line (drawable, gc,
- location->x + i - offset, location->y,
- location->x + i - offset, location->y + location->height - 1);
-
- if (draw_arrow)
- {
- if (direction == GTK_TEXT_DIR_RTL)
- {
- x = location->x - offset - 1;
- y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
-
- for (i = 0; i < arrow_width; i++)
- {
- gdk_draw_line (drawable, gc,
- x, y + i + 1,
- x, y + 2 * arrow_width - i - 1);
- x --;
- }
- }
- else if (direction == GTK_TEXT_DIR_LTR)
- {
- x = location->x + stem_width - offset;
- y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
-
- for (i = 0; i < arrow_width; i++)
- {
- gdk_draw_line (drawable, gc,
- x, y + i + 1,
- x, y + 2 * arrow_width - i - 1);
- x++;
- }
- }
- }
-}
-
-static void
-gtk_entry_draw_cursor (GtkEntry *entry,
- CursorType type)
-{
- GtkTextDirection keymap_direction =
- (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ?
- GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
- GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry));
-
- if (GTK_WIDGET_DRAWABLE (entry) && GTK_ENTRY(entry)->cursor_visible)
- {
- GtkWidget *widget = GTK_WIDGET (entry);
- GdkRectangle cursor_location;
- gboolean split_cursor;
-
- gint xoffset = INNER_BORDER - entry->scroll_offset;
- gint strong_x, weak_x;
- gint text_area_height;
- GtkTextDirection dir1 = GTK_TEXT_DIR_NONE;
- GtkTextDirection dir2 = GTK_TEXT_DIR_NONE;
- gint x1 = 0;
- gint x2 = 0;
- GdkGC *gc;
-
- gdk_window_get_size (entry->text_area, NULL, &text_area_height);
-
- gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x);
-
- g_object_get (gtk_widget_get_settings (widget),
- "gtk-split-cursor", &split_cursor,
- NULL);
-
- dir1 = widget_direction;
-
- if (split_cursor)
- {
- x1 = strong_x;
-
- if (weak_x != strong_x)
- {
- dir2 = (widget_direction == GTK_TEXT_DIR_LTR) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
- x2 = weak_x;
- }
- }
- else
- {
- if (keymap_direction == widget_direction)
- x1 = strong_x;
- else
- x1 = weak_x;
- }
-
- cursor_location.x = xoffset + x1;
- cursor_location.y = INNER_BORDER;
- cursor_location.width = 0;
- cursor_location.height = text_area_height - 2 * INNER_BORDER ;
-
- gc = _gtkextra_get_insertion_cursor_gc (widget, TRUE);
- _gtkextra_draw_insertion_cursor (widget, entry->text_area, gc,
- &cursor_location, dir1,
- dir2 != GTK_TEXT_DIR_NONE);
- g_object_unref (gc);
-
- if (dir2 != GTK_TEXT_DIR_NONE)
- {
- cursor_location.x = xoffset + x2;
- gc = _gtkextra_get_insertion_cursor_gc (widget, FALSE);
- _gtkextra_draw_insertion_cursor (widget, entry->text_area, gc,
- &cursor_location, dir2,
- TRUE);
- g_object_unref (gc);
- }
- }
-}
-
-static void
-gtk_entry_queue_draw (GtkEntry *entry)
-{
- if (GTK_WIDGET_REALIZED (entry))
- gdk_window_invalidate_rect (entry->text_area, NULL, FALSE);
-}
-
-static void
-gtk_entry_reset_im_context (GtkEntry *entry)
-{
- if (entry->need_im_reset)
- {
- entry->need_im_reset = 0;
- gtk_im_context_reset (entry->im_context);
- }
-}
-
-static void
-gtk_entry_get_cursor_locations (GtkEntry *entry,
- CursorType type,
- gint *strong_x,
- gint *weak_x)
-{
- PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
- const gchar *text;
- PangoRectangle strong_pos, weak_pos;
- gint index;
-
- if (type == CURSOR_STANDARD)
- {
- text = pango_layout_get_text (layout);
- index = g_utf8_offset_to_pointer (text, entry->current_pos + entry->preedit_cursor) - text;
- }
- else /* type == CURSOR_DND */
- {
- index = g_utf8_offset_to_pointer (entry->text, entry->dnd_position) - entry->text;
- if (entry->dnd_position > entry->current_pos)
- index += entry->preedit_length;
- }
-
- pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
-
- if (strong_x)
- *strong_x = strong_pos.x / PANGO_SCALE;
-
- if (weak_x)
- *weak_x = weak_pos.x / PANGO_SCALE;
-}
-
-static void
-gtk_entry_adjust_scroll (GtkEntry *entry)
-{
- gint min_offset, max_offset;
- gint text_area_width;
- gint strong_x, weak_x;
- PangoLayout *layout;
- PangoLayoutLine *line;
- PangoRectangle logical_rect;
- GtkItemEntry *item_entry;
- gint text_width;
-
- if (!GTK_WIDGET_REALIZED (entry))
- return;
-
- item_entry = GTK_ITEM_ENTRY(entry);
-
- gdk_window_get_size (entry->text_area, &text_area_width, NULL);
- text_area_width -= 2 * INNER_BORDER;
-
- layout = gtk_entry_ensure_layout (entry, TRUE);
- line = pango_layout_get_lines (layout)->data;
-
- pango_layout_line_get_extents (line, NULL, &logical_rect);
- text_width = logical_rect.width / PANGO_SCALE + 2; /* 2 for cursor */
-
- gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
-
- /* Display as much text as we can */
-
- if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_LTR)
- {
- entry->scroll_offset = 0;
- switch(item_entry->justification){
-
- case GTK_JUSTIFY_FILL:
- case GTK_JUSTIFY_LEFT:
-
-/* LEFT JUSTIFICATION */
-
- strong_x -= entry->scroll_offset;
- if (strong_x < 0)
- entry->scroll_offset += strong_x;
- else if (strong_x > text_area_width){
- if(item_entry->text_max_size != 0 &&
- text_area_width + 2 <= item_entry->text_max_size){
- GtkAllocation allocation;
- allocation = GTK_WIDGET(entry)->allocation;
- allocation.width += text_width - text_area_width;
- entry->scroll_offset = 0;
- gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation);
- }else{
- entry->scroll_offset += (strong_x - text_area_width) + 1;
- }
- }
-
- break;
-
- case GTK_JUSTIFY_RIGHT:
-
- /* RIGHT JUSTIFICATION FOR NUMBERS */
- if(entry->text){
-
- entry->scroll_offset= -(text_area_width - text_width) + 1;
- if(entry->scroll_offset > 0){
- if(item_entry->text_max_size != 0 &&
- text_area_width + 2 <= item_entry->text_max_size){
- GtkAllocation allocation;
- allocation = GTK_WIDGET(entry)->allocation;
- allocation.x -= text_width - text_area_width;
- allocation.width += text_width - text_area_width;
- entry->scroll_offset = 0;
- gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation);
- }
- else
- {
- entry->scroll_offset= -(text_area_width - strong_x) + 1;
- if(entry->scroll_offset < 0) entry->scroll_offset = 0;
- }
- }
- }
- else
- entry->scroll_offset=0;
-
- break;
- case GTK_JUSTIFY_CENTER:
-
- if(entry->text){
-
- entry->scroll_offset= -(text_area_width - text_width)/2;
- if(entry->scroll_offset > 0){
- if(item_entry->text_max_size != 0 &&
- text_area_width+1<=item_entry->text_max_size){
- GtkAllocation allocation;
- allocation = GTK_WIDGET(entry)->allocation;
- allocation.x += (text_area_width/2 - text_width/2);
- allocation.width += text_width - text_area_width;
- entry->scroll_offset = 0;
- gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation);
- }
- else
- {
- entry->scroll_offset= -(text_area_width - strong_x) + 1;
- if(entry->scroll_offset < 0) entry->scroll_offset = 0;
- }
- }
- }
- else
- entry->scroll_offset=0;
-
- break;
-
- }
-
- }
- else
- {
- max_offset = text_width - text_area_width;
- min_offset = MIN (0, max_offset);
- entry->scroll_offset = CLAMP (entry->scroll_offset, min_offset, max_offset);
- }
-
- g_object_notify (G_OBJECT (entry), "scroll_offset");
-}
-
-static gint
-gtk_entry_move_visually (GtkEntry *entry,
- gint start,
- gint count)
-{
- gint index;
- PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
- const gchar *text;
-
- text = pango_layout_get_text (layout);
-
- index = g_utf8_offset_to_pointer (text, start) - text;
-
- while (count != 0)
- {
- int new_index, new_trailing;
- gboolean split_cursor;
- gboolean strong;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)),
- "gtk-split-cursor", &split_cursor,
- NULL);
-
- if (split_cursor)
- strong = TRUE;
- else
- {
- GtkTextDirection keymap_direction =
- (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ?
- GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
-
- strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (entry));
- }
-
- if (count > 0)
- {
- pango_layout_move_cursor_visually (layout, strong, index, 0, 1, &new_index, &new_trailing);
- count--;
- }
- else
- {
- pango_layout_move_cursor_visually (layout, strong, index, 0, -1, &new_index, &new_trailing);
- count++;
- }
-
- if (new_index < 0 || new_index == G_MAXINT)
- break;
-
- index = new_index;
-
- while (new_trailing--)
- index = g_utf8_next_char (entry->text + new_index) - entry->text;
- }
-
- return g_utf8_pointer_to_offset (text, text + index);
-}
-
-static gint
-gtk_entry_move_logically (GtkEntry *entry,
- gint start,
- gint count)
-{
- gint new_pos = start;
-
- /* Prevent any leak of information */
- if (!entry->visible)
- {
- new_pos = CLAMP (start + count, 0, entry->text_length);
- }
- else if (entry->text)
- {
- PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
- PangoLogAttr *log_attrs;
- gint n_attrs;
-
- pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
-
- while (count > 0 && new_pos < entry->text_length)
- {
- do
- new_pos++;
- while (new_pos < entry->text_length && !log_attrs[new_pos].is_cursor_position);
-
- count--;
- }
- while (count < 0 && new_pos > 0)
- {
- do
- new_pos--;
- while (new_pos > 0 && !log_attrs[new_pos].is_cursor_position);
-
- count++;
- }
-
- g_free (log_attrs);
- }
-
- return new_pos;
-}
-
-static gint
-gtk_entry_move_forward_word (GtkEntry *entry,
- gint start)
-{
- gint new_pos = start;
-
- /* Prevent any leak of information */
- if (!entry->visible)
- {
- new_pos = entry->text_length;
- }
- else if (entry->text && (new_pos < entry->text_length))
- {
- PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
- PangoLogAttr *log_attrs;
- gint n_attrs;
-
- pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
-
- /* Find the next word end */
- new_pos++;
- while (new_pos < n_attrs && !log_attrs[new_pos].is_word_end)
- new_pos++;
-
- g_free (log_attrs);
- }
-
- return new_pos;
-}
-
-
-static gint
-gtk_entry_move_backward_word (GtkEntry *entry,
- gint start)
-{
- gint new_pos = start;
-
- /* Prevent any leak of information */
- if (!entry->visible)
- {
- new_pos = 0;
- }
- else if (entry->text && start > 0)
- {
- PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
- PangoLogAttr *log_attrs;
- gint n_attrs;
-
- pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
-
- new_pos = start - 1;
-
- /* Find the previous word beginning */
- while (new_pos > 0 && !log_attrs[new_pos].is_word_start)
- new_pos--;
-
- g_free (log_attrs);
- }
-
- return new_pos;
-}
-
-static void
-gtk_entry_delete_whitespace (GtkEntry *entry)
-{
- PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
- PangoLogAttr *log_attrs;
- gint n_attrs;
- gint start, end;
-
- pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
-
- start = end = entry->current_pos;
-
- while (start > 0 && log_attrs[start-1].is_white)
- start--;
-
- while (end < n_attrs && log_attrs[end].is_white)
- end++;
-
- g_free (log_attrs);
-
- if (start != end)
- gtk_editable_delete_text (GTK_EDITABLE (entry), start, end);
-}
-
-
-/*
- * Like gtk_editable_get_chars, but if the editable is not
- * visible, return asterisks; also convert result to UTF-8.
- */
-static char *
-gtk_entry_get_public_chars (GtkEntry *entry,
- gint start,
- gint end)
-{
- if (end < 0)
- end = entry->text_length;
-
- if (entry->visible)
- return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
- else
- {
- gchar *str;
- gint i;
- gint n_chars = end - start;
-
- str = g_malloc (n_chars + 1);
- for (i = 0; i < n_chars; i++)
- str[i] = '*';
- str[i] = '\0';
-
- return str;
- }
-
-}
-
-static void
-primary_get_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer data)
-{
- GtkEntry *entry = GTK_ENTRY (data);
- gint start, end;
-
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
- {
- gchar *str = gtk_entry_get_public_chars (entry, start, end);
- gtk_selection_data_set_text (selection_data, str, -1);
- g_free (str);
- }
-}
-
-static void
-primary_clear_cb (GtkClipboard *clipboard,
- gpointer data)
-{
- GtkEntry *entry = GTK_ENTRY (data);
-
- gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos);
-}
-
-static void
-gtk_entry_update_primary_selection (GtkEntry *entry)
-{
- static const GtkTargetEntry targets[] = {
- { "UTF8_STRING", 0, 0 },
- { "STRING", 0, 0 },
- { "TEXT", 0, 0 },
- { "COMPOUND_TEXT", 0, 0 }
- };
-
- GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
- gint start, end;
-
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
- {
- if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
- primary_get_cb, primary_clear_cb, G_OBJECT (entry)))
- primary_clear_cb (clipboard, entry);
- }
- else
- {
- if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
- gtk_clipboard_clear (clipboard);
- }
-}
-
-/* Public API
- */
-
-GtkWidget*
-gtk_item_entry_new (void)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (gtk_type_new (GTK_TYPE_ITEM_ENTRY));
- return widget;
-}
-
-GtkWidget*
-gtk_item_entry_new_with_max_length (gint max)
-{
- GtkItemEntry *entry;
-
- entry = gtk_type_new (GTK_TYPE_ITEM_ENTRY);
- gtk_entry_set_max_length(GTK_ENTRY(entry), max);
-
- return GTK_WIDGET (entry);
-}
-
-void
-gtk_item_entry_set_text (GtkItemEntry *entry,
- const gchar *text,
- GtkJustification justification)
-{
- gint tmp_pos;
-
- g_return_if_fail (GTK_IS_ITEM_ENTRY (entry));
- g_return_if_fail (text != NULL);
-
- entry->justification = justification;
-
- /* Actually setting the text will affect the cursor and selection;
- * if the contents don't actually change, this will look odd to the user.
- */
- if (strcmp (GTK_ENTRY(entry)->text, text) == 0)
- return;
-
- if (GTK_ENTRY(entry)->recompute_idle){
- g_source_remove (GTK_ENTRY(entry)->recompute_idle);
- GTK_ENTRY(entry)->recompute_idle = 0;
- }
- if (GTK_ENTRY(entry)->blink_timeout){
- g_source_remove (GTK_ENTRY(entry)->blink_timeout);
- GTK_ENTRY(entry)->blink_timeout = 0;
- }
-
- gtk_editable_delete_text (GTK_EDITABLE (entry), 0, -1);
-
- tmp_pos = 0;
- gtk_editable_insert_text (GTK_EDITABLE (entry), text, strlen (text), &tmp_pos);
-}
-
-/**
- * gtk_entry_get_layout_offsets:
- * @entry: a #GtkEntry
- * @x: location to store X offset of layout, or %NULL
- * @y: location to store Y offset of layout, or %NULL
- *
- *
- * Obtains the position of the #PangoLayout used to render text
- * in the entry, in widget coordinates. Useful if you want to line
- * up the text in an entry with some other text, e.g. when using the
- * entry to implement editable cells in a sheet widget.
- *
- * Also useful to convert mouse events into coordinates inside the
- * #PangoLayout, e.g. to take some action if some part of the entry text
- * is clicked.
- *
- * Note that as the user scrolls around in the entry the offsets will
- * change; you'll need to connect to the "notify::scroll_offset"
- * signal to track this. Remember when using the #PangoLayout
- * functions you need to convert to and from pixels using
- * PANGO_PIXELS() or #PANGO_SCALE.
- *
- * Keep in mind that the layout text may contain a preedit string, so
- * gtk_entry_layout_index_to_text_index() and
- * gtk_entry_text_index_to_layout_index() are needed to convert byte
- * indices in the layout to byte indices in the entry contents.
- *
- **/
-void
-gtk_item_entry_get_layout_offsets (GtkItemEntry *entry,
- gint *x,
- gint *y)
-{
- gint text_area_x, text_area_y;
-
- g_return_if_fail (GTK_IS_ITEM_ENTRY (entry));
-
- /* this gets coords relative to text area */
- get_layout_position (GTK_ENTRY(entry), x, y);
-
- /* convert to widget coords */
- get_text_area_size (GTK_ENTRY(entry), &text_area_x, &text_area_y, NULL, NULL);
-
- if (x)
- *x += text_area_x;
-
- if (y)
- *y += text_area_y;
-}
-
-void
-gtk_item_entry_set_justification(GtkItemEntry *entry, GtkJustification just)
-{
- g_return_if_fail (GTK_IS_ITEM_ENTRY (entry));
-
- entry->justification = just;
-}
-
-
-/* We display the cursor when
- *
- * - the selection is empty, AND
- * - the widget has focus
- */
-
-#define CURSOR_ON_MULTIPLIER 0.66
-#define CURSOR_OFF_MULTIPLIER 0.34
-#define CURSOR_PEND_MULTIPLIER 1.0
-
-static gboolean
-cursor_blinks (GtkEntry *entry)
-{
- GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
- gboolean blink;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) &&
- entry->selection_bound == entry->current_pos)
- {
- g_object_get (G_OBJECT (settings), "gtk-cursor-blink", &blink, NULL);
- return blink;
- }
- else
- return FALSE;
-}
-
-static gint
-get_cursor_time (GtkEntry *entry)
-{
- GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
- gint time;
-
- g_object_get (G_OBJECT (settings), "gtk-cursor-blink-time", &time, NULL);
-
- return time;
-}
-
-static void
-show_cursor (GtkEntry *entry)
-{
- if (!entry->cursor_visible)
- {
- entry->cursor_visible = TRUE;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos)
- gtk_widget_queue_draw (GTK_WIDGET (entry));
- }
-}
-
-static void
-hide_cursor (GtkEntry *entry)
-{
- if (entry->cursor_visible)
- {
- entry->cursor_visible = FALSE;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos)
- gtk_widget_queue_draw (GTK_WIDGET (entry));
- }
-}
-
-/*
- * Blink!
- */
-static gint
-blink_cb (gpointer data)
-{
- GtkEntry *entry;
-
- GDK_THREADS_ENTER ();
-
- entry = GTK_ENTRY (data);
-
- g_assert (GTK_WIDGET_HAS_FOCUS (entry));
- g_assert (entry->selection_bound == entry->current_pos);
-
- if (entry->cursor_visible)
- {
- hide_cursor (entry);
- entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER,
- blink_cb,
- entry);
- }
- else
- {
- show_cursor (entry);
- entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
- blink_cb,
- entry);
- }
-
- GDK_THREADS_LEAVE ();
-
- /* Remove ourselves */
- return FALSE;
-}
-
-static void
-gtk_entry_check_cursor_blink (GtkEntry *entry)
-{
- if (cursor_blinks (entry))
- {
- if (!entry->blink_timeout)
- {
- entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
- blink_cb,
- entry);
- show_cursor (entry);
- }
- }
- else
- {
- if (entry->blink_timeout)
- {
- gtk_timeout_remove (entry->blink_timeout);
- entry->blink_timeout = 0;
- }
-
- entry->cursor_visible = TRUE;
- }
-
-}
-
-static void
-gtk_entry_pend_cursor_blink (GtkEntry *entry)
-{
- if (cursor_blinks (entry))
- {
- if (entry->blink_timeout != 0)
- gtk_timeout_remove (entry->blink_timeout);
-
- entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER,
- blink_cb,
- entry);
- show_cursor (entry);
- }
-}
-
-void
-gtk_item_entry_set_cursor_visible(GtkItemEntry *entry, gboolean visible)
-{
- g_return_if_fail (GTK_IS_ITEM_ENTRY (entry));
-
- GTK_ENTRY(entry)->cursor_visible = visible;
-}
-
-gboolean
-gtk_item_entry_get_cursor_visible(GtkItemEntry *entry)
-{
- g_return_val_if_fail (GTK_IS_ITEM_ENTRY (entry), FALSE);
-
- return(GTK_ENTRY(entry)->cursor_visible);
-}
+++ /dev/null
-/* GtkItemEntry - widget for gtk+
- * Copyright (C) 1999-2001 Adrian E. Feiguin <adrian@ifir.ifir.edu.ar>
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * GtkItemEntry widget by Adrian E. Feiguin
- * Based on GtkEntry widget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef __GTK_ITEM_ENTRY_H__
-#define __GTK_ITEM_ENTRY_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define GTK_TYPE_ITEM_ENTRY (gtk_item_entry_get_type ())
-#define GTK_ITEM_ENTRY(obj) (GTK_CHECK_CAST (obj, gtk_item_entry_get_type (), GtkItemEntry))
-#define GTK_ITEM_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, gtk_item_entry_get_type (), GtkItemEntryClass))
-#define GTK_IS_ITEM_ENTRY(obj) (GTK_CHECK_TYPE (obj, gtk_item_entry_get_type ()))
-#define GTK_IS_ITEM_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY))
-
-
-typedef struct _GtkItemEntry GtkItemEntry;
-typedef struct _GtkItemEntryClass GtkItemEntryClass;
-
-struct _GtkItemEntry
-{
- GtkEntry parent;
-
- gint text_max_size;
-
- GtkJustification justification;
-};
-
-struct _GtkItemEntryClass
-{
- GtkEntryClass parent_class;
-};
-
-GtkType gtk_item_entry_get_type (void);
-GtkWidget* gtk_item_entry_new (void);
-GtkWidget* gtk_item_entry_new_with_max_length (gint max);
-void gtk_item_entry_set_text (GtkItemEntry *item_entry,
- const gchar *text,
- GtkJustification justification);
-
-void gtk_item_entry_set_justification (GtkItemEntry *item_entry,
- GtkJustification justification);
-
-void gtk_item_entry_set_cursor_visible (GtkItemEntry *entry,
- gboolean visible);
-gboolean gtk_item_entry_get_cursor_visible (GtkItemEntry *entry);
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __GTK_ITEM_ENTRY_H__ */
*
* GtkSheet is a matrix widget for GTK+. It consists of an scrollable grid of
* cells where you can allocate text. Cell contents can be edited interactively
- * through a specially designed entry, GtkItemEntry. It is also a container
- * subclass, allowing you to display buttons, curves, pixmaps and any other
- * widgets in it.
+ * through a specially designed entry, GtkItemEntry.
*
- * You can also set many attributes as: border, foreground and background color,
- * text justification, and more.
- *
- * The testgtksheet program shows how easy is to create a spreadsheet-like GUI
- * using this widget.
*/
#include <config.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtksignal.h>
-#include <gtk/gtklabel.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkadjustment.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtkbox.h>
-#include <gtk/gtkmain.h>
#include <gtk/gtktypeutils.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkcontainer.h>
-#include <gtk/gtkpixmap.h>
#include <pango/pango.h>
-#include "gtkitementry.h"
#include "gtksheet.h"
-#include "gtkextra-marshal.h"
+#include <gtksheet/psppire-marshal.h>
#include "gsheetmodel.h"
+#include <libpspp/misc.h>
+#include <math.h>
/* sheet flags */
enum
{
- GTK_SHEET_IS_FROZEN = 1 << 1,
- GTK_SHEET_IN_XDRAG = 1 << 2,
- GTK_SHEET_IN_YDRAG = 1 << 3,
- GTK_SHEET_IN_DRAG = 1 << 4,
- GTK_SHEET_IN_SELECTION = 1 << 5,
- GTK_SHEET_IN_RESIZE = 1 << 6,
- GTK_SHEET_REDRAW_PENDING = 1 << 7,
+ GTK_SHEET_IN_XDRAG = 1 << 1,
+ GTK_SHEET_IN_YDRAG = 1 << 2,
+ GTK_SHEET_IN_DRAG = 1 << 3,
+ GTK_SHEET_IN_SELECTION = 1 << 4,
+ GTK_SHEET_IN_RESIZE = 1 << 5
};
#define GTK_SHEET_FLAGS(sheet) (GTK_SHEET (sheet)->flags)
#define GTK_SHEET_SET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) |= (flag))
#define GTK_SHEET_UNSET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) &= ~ (flag))
-#define GTK_SHEET_IS_FROZEN(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN)
#define GTK_SHEET_IN_XDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG)
#define GTK_SHEET_IN_YDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG)
#define GTK_SHEET_IN_DRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_DRAG)
#define GTK_SHEET_IN_SELECTION(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_SELECTION)
#define GTK_SHEET_IN_RESIZE(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_RESIZE)
-#define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING)
#define CELL_SPACING 1
-#define DRAG_WIDTH 6
+
#define TIMEOUT_HOVER 300
#define COLUMN_MIN_WIDTH 10
-#define CELLOFFSET 4
+#define COLUMN_TITLES_HEIGHT 4
#define DEFAULT_COLUMN_WIDTH 80
+#define DEFAULT_ROW_HEIGHT 25
+
+static void set_entry_widget_font (GtkSheet *sheet);
static void gtk_sheet_update_primary_selection (GtkSheet *sheet);
-static void gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column);
+static void draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint n);
+static void draw_row_title_buttons_range (GtkSheet *sheet, gint first, gint n);
-static void gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row);
+static void set_row_height (GtkSheet *sheet,
+ gint row,
+ gint height);
+
+static void destroy_hover_window (GtkSheetHoverTitle *);
+static GtkSheetHoverTitle *create_hover_window (void);
+
+static GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col);
-static gboolean gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col);
static inline void
dispose_string (const GtkSheet *sheet, gchar *text)
g_free (text);
}
-static inline
-guint DEFAULT_ROW_HEIGHT (GtkWidget *widget)
-{
- if (!widget->style->font_desc) return 24;
- else
- {
- PangoContext *context = gtk_widget_get_pango_context (widget);
- PangoFontMetrics *metrics =
- pango_context_get_metrics (context,
- widget->style->font_desc,
- pango_context_get_language (context));
-
- guint val = pango_font_metrics_get_descent (metrics) +
- pango_font_metrics_get_ascent (metrics);
-
- pango_font_metrics_unref (metrics);
-
- return PANGO_PIXELS (val) + 2 * CELLOFFSET;
- }
-}
-
-static inline
-guint DEFAULT_FONT_ASCENT (GtkWidget *widget)
-{
- if (!widget->style->font_desc) return 12;
- else
- {
- PangoContext *context = gtk_widget_get_pango_context (widget);
- PangoFontMetrics *metrics =
- pango_context_get_metrics (context,
- widget->style->font_desc,
- pango_context_get_language (context));
- guint val = pango_font_metrics_get_ascent (metrics);
- pango_font_metrics_unref (metrics);
- return PANGO_PIXELS (val);
- }
-}
-
-static inline
-guint STRING_WIDTH (GtkWidget *widget,
- const PangoFontDescription *font, const gchar *text)
-{
- PangoRectangle rect;
- PangoLayout *layout;
-
- layout = gtk_widget_create_pango_layout (widget, text);
- pango_layout_set_font_description (layout, font);
-
- pango_layout_get_extents (layout, NULL, &rect);
-
- g_object_unref (layout);
- return PANGO_PIXELS (rect.width);
-}
-
-static inline
-guint DEFAULT_FONT_DESCENT (GtkWidget *widget)
-{
- if (!widget->style->font_desc) return 12;
- else
- {
- PangoContext *context = gtk_widget_get_pango_context (widget);
- PangoFontMetrics *metrics =
- pango_context_get_metrics (context,
- widget->style->font_desc,
- pango_context_get_language (context));
- guint val = pango_font_metrics_get_descent (metrics);
- pango_font_metrics_unref (metrics);
- return PANGO_PIXELS (val);
- }
-}
-
-
-static gint
-yyy_row_is_visible (const GtkSheet *sheet, gint row)
-{
- GSheetRow *row_geo = sheet->row_geometry;
-
- return g_sheet_row_get_visibility (row_geo, row);
-}
-
-
-static gint
-yyy_row_is_sensitive (const GtkSheet *sheet, gint row)
-{
- GSheetRow *row_geo = sheet->row_geometry;
-
- return g_sheet_row_get_sensitivity (row_geo, row);
-}
-
+/* FIXME: Why bother with these two ? */
+/* returns the column index from a pixel location */
static inline gint
-yyy_row_count (const GtkSheet *sheet)
+column_from_xpixel (const GtkSheet *sheet, gint pixel)
{
- GSheetRow *row_geo = sheet->row_geometry;
-
- return g_sheet_row_get_row_count (row_geo);
+ return psppire_axis_unit_at_pixel (sheet->haxis, pixel);
}
static inline gint
-yyy_row_height (const GtkSheet *sheet, gint row)
-{
- GSheetRow *row_geo = sheet->row_geometry;
-
- return g_sheet_row_get_height (row_geo, row);
-}
-
-static gint
-yyy_row_top_ypixel (const GtkSheet *sheet, gint row)
+row_from_ypixel (const GtkSheet *sheet, gint pixel)
{
- GSheetRow *geo = sheet->row_geometry;
-
- gint y = g_sheet_row_start_pixel (geo, row);
-
- if ( sheet->column_titles_visible )
- y += sheet->column_title_area.height;
-
- return y;
+ return psppire_axis_unit_at_pixel (sheet->vaxis, pixel);
}
-/* Return the row containing pixel Y */
-static gint
-yyy_row_ypixel_to_row (const GtkSheet *sheet, gint y)
+/* Return the lowest row number which is wholly or partially on
+ the visible range of the sheet */
+static inline glong
+min_visible_row (const GtkSheet *sheet)
{
- GSheetRow *geo = sheet->row_geometry;
-
- gint cy = sheet->voffset;
-
- if (sheet->column_titles_visible)
- cy += sheet->column_title_area.height;
-
- if (y < cy) return 0;
-
- return g_sheet_row_pixel_to_row (geo, y - cy);
+ return row_from_ypixel (sheet, sheet->vadjustment->value);
}
-
-/* gives the top pixel of the given row in context of
- * the sheet's voffset */
-static inline gint
-ROW_TOP_YPIXEL (const GtkSheet *sheet, gint row)
+static inline glong
+min_fully_visible_row (const GtkSheet *sheet)
{
- return (sheet->voffset + yyy_row_top_ypixel (sheet, row));
-}
+ glong row = min_visible_row (sheet);
+ if ( psppire_axis_start_pixel (sheet->vaxis, row) < sheet->vadjustment->value)
+ row++;
-/* returns the row index from a y pixel location in the
- * context of the sheet's voffset */
-static inline gint
-ROW_FROM_YPIXEL (const GtkSheet *sheet, gint y)
-{
- return (yyy_row_ypixel_to_row (sheet, y));
+ return row;
}
-static inline GtkSheetButton *
-xxx_column_button (const GtkSheet *sheet, gint col)
+static inline glong
+max_visible_row (const GtkSheet *sheet)
{
- GSheetColumn *col_geo = sheet->column_geometry;
- if ( col < 0 ) return NULL ;
-
- return g_sheet_column_get_button (col_geo, col);
+ return row_from_ypixel (sheet, sheet->vadjustment->value + sheet->vadjustment->page_size);
}
-static inline gint
-xxx_column_left_xpixel (const GtkSheet *sheet, gint col)
+static inline glong
+max_fully_visible_row (const GtkSheet *sheet)
{
- GSheetColumn *geo = sheet->column_geometry;
-
- gint x = g_sheet_column_start_pixel (geo, col);
-
- if ( sheet->row_titles_visible )
- x += sheet->row_title_area.width;
+ glong row = max_visible_row (sheet);
- return x;
-}
-
-static inline gint
-xxx_column_width (const GtkSheet *sheet, gint col)
-{
- GSheetColumn *col_geo = sheet->column_geometry;
+ if ( psppire_axis_start_pixel (sheet->vaxis, row)
+ +
+ psppire_axis_unit_size (sheet->vaxis, row)
+ > sheet->vadjustment->value)
+ row--;
- return g_sheet_column_get_width (col_geo, col);
+ return row;
}
-static inline void
-xxx_set_column_width (GtkSheet *sheet, gint col, gint width)
+/* Returns the lowest column number which is wholly or partially
+ on the sheet */
+static inline glong
+min_visible_column (const GtkSheet *sheet)
{
- if ( sheet->column_geometry )
- g_sheet_column_set_width (sheet->column_geometry, col, width);
+ return column_from_xpixel (sheet, sheet->hadjustment->value);
}
-static inline void
-xxx_column_set_left_column (GtkSheet *sheet, gint col, gint i)
+static inline glong
+min_fully_visible_column (const GtkSheet *sheet)
{
- GSheetColumn *col_geo = sheet->column_geometry;
+ glong col = min_visible_column (sheet);
- g_sheet_column_set_left_text_column (col_geo, col, i);
-}
-
-static inline gint
-xxx_column_left_column (const GtkSheet *sheet, gint col)
-{
- GSheetColumn *col_geo = sheet->column_geometry;
+ if ( psppire_axis_start_pixel (sheet->haxis, col) < sheet->hadjustment->value)
+ col++;
- return g_sheet_column_get_left_text_column (col_geo, col);
+ return col;
}
-static inline void
-xxx_column_set_right_column (GtkSheet *sheet, gint col, gint i)
-{
- GSheetColumn *col_geo = sheet->column_geometry;
-
- g_sheet_column_set_right_text_column (col_geo, col, i);
-}
-static inline gint
-xxx_column_right_column (const GtkSheet *sheet, gint col)
+/* Returns the highest column number which is wholly or partially
+ on the sheet */
+static inline glong
+max_visible_column (const GtkSheet *sheet)
{
- GSheetColumn *col_geo = sheet->column_geometry;
-
- return g_sheet_column_get_right_text_column (col_geo, col);
+ return column_from_xpixel (sheet, sheet->hadjustment->value + sheet->hadjustment->page_size);
}
-static inline GtkJustification
-xxx_column_justification (const GtkSheet *sheet, gint col)
+static inline glong
+max_fully_visible_column (const GtkSheet *sheet)
{
- GSheetColumn *col_geo = sheet->column_geometry;
-
- return g_sheet_column_get_justification (col_geo, col);
-}
+ glong col = max_visible_column (sheet);
-static inline gint
-xxx_column_is_visible (const GtkSheet *sheet, gint col)
-{
- GSheetColumn *col_geo = sheet->column_geometry;
+ if ( psppire_axis_start_pixel (sheet->haxis, col)
+ +
+ psppire_axis_unit_size (sheet->haxis, col)
+ > sheet->hadjustment->value)
+ col--;
- return g_sheet_column_get_visibility (col_geo, col);
+ return col;
}
-static inline gint
-xxx_column_is_sensitive (const GtkSheet *sheet, gint col)
-{
- GSheetColumn *col_geo = sheet->column_geometry;
-
- return g_sheet_column_get_sensitivity (col_geo, col);
-}
-
-/* gives the left pixel of the given column in context of
- * the sheet's hoffset */
-static inline gint
-COLUMN_LEFT_XPIXEL (const GtkSheet *sheet, gint ncol)
-{
- return (sheet->hoffset + xxx_column_left_xpixel (sheet, ncol));
-}
+/* The size of the region (in pixels) around the row/column boundaries
+ where the height/width may be grabbed to change size */
+#define DRAG_WIDTH 6
-static inline gint
-xxx_column_count (const GtkSheet *sheet)
+static gboolean
+on_column_boundary (const GtkSheet *sheet, gint x, gint *column)
{
- GSheetColumn *col_geo = sheet->column_geometry;
-
- return g_sheet_column_get_column_count (col_geo);
-}
+ gint col;
-/* returns the column index from a x pixel location in the
- * context of the sheet's hoffset */
-static inline gint
-COLUMN_FROM_XPIXEL (const GtkSheet * sheet,
- gint x)
-{
- gint i, cx;
+ x += sheet->hadjustment->value;
- cx = sheet->hoffset;
- if ( sheet->row_titles_visible )
- cx += sheet->row_title_area.width;
+ col = column_from_xpixel (sheet, x);
- if (x < cx) return 0;
- for (i = 0; i < xxx_column_count (sheet); i++)
+ if ( column_from_xpixel (sheet, x - DRAG_WIDTH / 2) < col )
{
- if (x >= cx && x <= (cx + xxx_column_width (sheet, i)) &&
- xxx_column_is_visible (sheet, i))
- return i;
- if ( xxx_column_is_visible (sheet, i))
- cx += xxx_column_width (sheet, i);
+ *column = col - 1;
+ return TRUE;
}
- /* no match */
- return xxx_column_count (sheet) - 1;
-}
-
-/* returns the total height of the sheet */
-static inline gint SHEET_HEIGHT (GtkSheet *sheet)
-{
- const gint n_rows = yyy_row_count (sheet);
-
- return yyy_row_top_ypixel (sheet, n_rows - 1) +
- yyy_row_height (sheet, n_rows - 1);
-}
-
-
-static inline GtkSheetButton *
-yyy_row_button (GtkSheet *sheet, gint row)
-{
- GSheetRow *row_geo = sheet->row_geometry;
-
- return g_sheet_row_get_button (row_geo, row);
-}
-
-
-
+ if ( column_from_xpixel (sheet, x + DRAG_WIDTH / 2) > col )
+ {
+ *column = col;
+ return TRUE;
+ }
-static inline void
-yyy_set_row_height (GtkSheet *sheet, gint row, gint height)
-{
- if ( sheet->row_geometry )
- g_sheet_row_set_height (sheet->row_geometry, row, height);
+ return FALSE;
}
-
-
-/* returns the total width of the sheet */
-static inline gint SHEET_WIDTH (GtkSheet *sheet)
+static gboolean
+on_row_boundary (const GtkSheet *sheet, gint y, gint *row)
{
- gint i, cx;
-
- cx = ( sheet->row_titles_visible ? sheet->row_title_area.width : 0);
+ gint r;
- for (i = 0; i < xxx_column_count (sheet); i++)
- if (xxx_column_is_visible (sheet, i))
- cx += xxx_column_width (sheet, i);
+ y += sheet->vadjustment->value;
- return cx;
-}
-
-#define MIN_VISIBLE_ROW(sheet) \
- ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1)
-
-#define MAX_VISIBLE_ROW(sheet) \
- ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1)
-
-#define MIN_VISIBLE_COLUMN(sheet) \
- COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1)
-
-#define MAX_VISIBLE_COLUMN(sheet) \
- COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width)
-
-
-
-static inline gboolean
-POSSIBLE_XDRAG (const GtkSheet *sheet, gint x, gint *drag_column)
-{
- gint column, xdrag;
+ r = row_from_ypixel (sheet, y);
- column = COLUMN_FROM_XPIXEL (sheet, x);
- *drag_column = column;
-
- xdrag = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING;
- if (x <= xdrag + DRAG_WIDTH / 2 && column != 0)
+ if ( row_from_ypixel (sheet, y - DRAG_WIDTH / 2) < r )
{
- while (! xxx_column_is_visible (sheet, column - 1) && column > 0) column--;
- *drag_column = column - 1;
- return xxx_column_is_sensitive (sheet, column - 1);
+ *row = r - 1;
+ return TRUE;
}
- xdrag += xxx_column_width (sheet, column);
- if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2)
- return xxx_column_is_sensitive (sheet, column);
-
- return FALSE;
-}
-
-static inline gboolean
-POSSIBLE_YDRAG (const GtkSheet *sheet, gint y, gint *drag_row)
-{
- gint row, ydrag;
- row = ROW_FROM_YPIXEL (sheet, y);
- *drag_row = row;
-
- ydrag = ROW_TOP_YPIXEL (sheet, row)+CELL_SPACING;
- if (y <= ydrag + DRAG_WIDTH / 2 && row != 0)
+ if ( row_from_ypixel (sheet, y + DRAG_WIDTH / 2) > r )
{
- while (!yyy_row_is_visible (sheet, row - 1) && row > 0) row--;
- *drag_row = row - 1;
- return yyy_row_is_sensitive (sheet, row - 1);
+ *row = r;
+ return TRUE;
}
- ydrag +=yyy_row_height (sheet, row);
-
- if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2)
- return yyy_row_is_sensitive (sheet, row);
-
-
return FALSE;
}
+
static inline gboolean
POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y,
gint *drag_row, gint *drag_column)
sheet->range.col0 < 0 || sheet->range.coli < 0 )
return FALSE;
- *drag_column = COLUMN_FROM_XPIXEL (sheet, x);
- *drag_row = ROW_FROM_YPIXEL (sheet, y);
+ *drag_column = column_from_xpixel (sheet, x);
+ *drag_row = row_from_ypixel (sheet, y);
- if (x >= COLUMN_LEFT_XPIXEL (sheet, sheet->range.col0) - DRAG_WIDTH / 2 &&
- x <= COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli) +
- xxx_column_width (sheet, sheet->range.coli) + DRAG_WIDTH / 2)
+ if (x >= psppire_axis_start_pixel (sheet->haxis, sheet->range.col0) - DRAG_WIDTH / 2 &&
+ x <= psppire_axis_start_pixel (sheet->haxis, sheet->range.coli) +
+ psppire_axis_unit_size (sheet->haxis, sheet->range.coli) + DRAG_WIDTH / 2)
{
- ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.row0);
+ ydrag = psppire_axis_start_pixel (sheet->vaxis, sheet->range.row0);
if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2)
{
*drag_row = sheet->range.row0;
return TRUE;
}
- ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.rowi) +
- yyy_row_height (sheet, sheet->range.rowi);
+ ydrag = psppire_axis_start_pixel (sheet->vaxis, sheet->range.rowi) +
+ psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi);
if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2)
{
*drag_row = sheet->range.rowi;
}
}
- if (y >= ROW_TOP_YPIXEL (sheet, sheet->range.row0) - DRAG_WIDTH / 2 &&
- y <= ROW_TOP_YPIXEL (sheet, sheet->range.rowi) +
- yyy_row_height (sheet, sheet->range.rowi) + DRAG_WIDTH / 2)
+ if (y >= psppire_axis_start_pixel (sheet->vaxis, sheet->range.row0) - DRAG_WIDTH / 2 &&
+ y <= psppire_axis_start_pixel (sheet->vaxis, sheet->range.rowi) +
+ psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi) + DRAG_WIDTH / 2)
{
- xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.col0);
+ xdrag = psppire_axis_start_pixel (sheet->haxis, sheet->range.col0);
if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2)
{
*drag_column = sheet->range.col0;
return TRUE;
}
- xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli) +
- xxx_column_width (sheet, sheet->range.coli);
+ xdrag = psppire_axis_start_pixel (sheet->haxis, sheet->range.coli) +
+ psppire_axis_unit_size (sheet->haxis, sheet->range.coli);
if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2)
{
*drag_column = sheet->range.coli;
sheet->range.col0 < 0 || sheet->range.coli < 0 )
return FALSE;
- xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli)+
- xxx_column_width (sheet, sheet->range.coli);
+ xdrag = psppire_axis_start_pixel (sheet->haxis, sheet->range.coli)+
+ psppire_axis_unit_size (sheet->haxis, sheet->range.coli);
- ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.rowi)+
- yyy_row_height (sheet, sheet->range.rowi);
+ ydrag = psppire_axis_start_pixel (sheet->vaxis, sheet->range.rowi) +
+ psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi);
if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- ydrag = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet));
+ ydrag = psppire_axis_start_pixel (sheet->vaxis, min_visible_row (sheet));
if (sheet->state == GTK_SHEET_ROW_SELECTED)
- xdrag = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet));
+ xdrag = psppire_axis_start_pixel (sheet->haxis, min_visible_column (sheet));
- *drag_column = COLUMN_FROM_XPIXEL (sheet, x);
- *drag_row = ROW_FROM_YPIXEL (sheet, y);
+ *drag_column = column_from_xpixel (sheet, x);
+ *drag_row = row_from_ypixel (sheet, y);
if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2 &&
y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) return TRUE;
return FALSE;
}
-static void gtk_sheet_class_init (GtkSheetClass * klass);
-static void gtk_sheet_init (GtkSheet * sheet);
-static void gtk_sheet_dispose (GObject * object);
-static void gtk_sheet_finalize (GObject * object);
+
+static gboolean
+rectangle_from_range (GtkSheet *sheet, const GtkSheetRange *range,
+ GdkRectangle *r)
+{
+ g_return_val_if_fail (range, FALSE);
+
+ r->x = psppire_axis_start_pixel (sheet->haxis, range->col0);
+ r->x -= round (sheet->hadjustment->value);
+
+ if ( sheet->row_titles_visible)
+ r->x += sheet->row_title_area.width;
+
+
+ r->y = psppire_axis_start_pixel (sheet->vaxis, range->row0);
+ r->y -= round (sheet->vadjustment->value);
+
+ if ( sheet->column_titles_visible)
+ r->y += sheet->column_title_area.height;
+
+ r->width = psppire_axis_start_pixel (sheet->haxis, range->coli) -
+ psppire_axis_start_pixel (sheet->haxis, range->col0) +
+ psppire_axis_unit_size (sheet->haxis, range->coli);
+
+ r->height = psppire_axis_start_pixel (sheet->vaxis, range->rowi) -
+ psppire_axis_start_pixel (sheet->vaxis, range->row0) +
+ psppire_axis_unit_size (sheet->vaxis, range->rowi);
+
+ return TRUE;
+}
+
+static gboolean
+rectangle_from_cell (GtkSheet *sheet, gint row, gint col,
+ GdkRectangle *r)
+{
+ GtkSheetRange range;
+ g_return_val_if_fail (row >= 0, FALSE);
+ g_return_val_if_fail (col >= 0, FALSE);
+
+ range.row0 = range.rowi = row;
+ range.col0 = range.coli = col;
+
+ return rectangle_from_range (sheet, &range, r);
+}
+
+
+static void gtk_sheet_class_init (GtkSheetClass *klass);
+static void gtk_sheet_init (GtkSheet *sheet);
+static void gtk_sheet_dispose (GObject *object);
+static void gtk_sheet_finalize (GObject *object);
static void gtk_sheet_style_set (GtkWidget *widget,
GtkStyle *previous_style);
-static void gtk_sheet_realize (GtkWidget * widget);
-static void gtk_sheet_unrealize (GtkWidget * widget);
-static void gtk_sheet_map (GtkWidget * widget);
-static void gtk_sheet_unmap (GtkWidget * widget);
-static gint gtk_sheet_expose (GtkWidget * widget,
- GdkEventExpose * event);
+static void gtk_sheet_realize (GtkWidget *widget);
+static void gtk_sheet_unrealize (GtkWidget *widget);
+static void gtk_sheet_map (GtkWidget *widget);
+static void gtk_sheet_unmap (GtkWidget *widget);
+static gint gtk_sheet_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+
static void gtk_sheet_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
-static gint gtk_sheet_button_press (GtkWidget * widget,
- GdkEventButton * event);
-static gint gtk_sheet_button_release (GtkWidget * widget,
- GdkEventButton * event);
-static gint gtk_sheet_motion (GtkWidget * widget,
- GdkEventMotion * event);
+static gint gtk_sheet_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gint gtk_sheet_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gint gtk_sheet_motion (GtkWidget *widget,
+ GdkEventMotion *event);
+static gboolean gtk_sheet_crossing_notify (GtkWidget *widget,
+ GdkEventCrossing *event);
static gint gtk_sheet_entry_key_press (GtkWidget *widget,
GdkEventKey *key);
-static gint gtk_sheet_key_press (GtkWidget *widget,
+static gboolean gtk_sheet_key_press (GtkWidget *widget,
GdkEventKey *key);
-static void gtk_sheet_size_request (GtkWidget * widget,
- GtkRequisition * requisition);
-static void gtk_sheet_size_allocate (GtkWidget * widget,
- GtkAllocation * allocation);
+static void gtk_sheet_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_sheet_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
/* Sheet queries */
-static gboolean gtk_sheet_range_isvisible (const GtkSheet * sheet,
- GtkSheetRange range);
-static gboolean gtk_sheet_cell_isvisible (GtkSheet * sheet,
+static gboolean gtk_sheet_range_isvisible (const GtkSheet *sheet,
+ const GtkSheetRange *range);
+static gboolean gtk_sheet_cell_isvisible (GtkSheet *sheet,
gint row, gint column);
/* Drawing Routines */
-/* draw cell background and frame */
-static void gtk_sheet_cell_draw_default (GtkSheet *sheet,
- gint row, gint column);
+/* draw cell */
+static void gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint column);
-/* draw cell contents */
-static void gtk_sheet_cell_draw_label (GtkSheet *sheet,
- gint row, gint column);
/* draw visible part of range. If range == NULL then draw the whole screen */
-static void gtk_sheet_range_draw (GtkSheet *sheet,
- const GtkSheetRange *range);
+static void gtk_sheet_range_draw (GtkSheet *sheet,
+ const GtkSheetRange *range);
/* highlight the visible part of the selected range */
static void gtk_sheet_range_draw_selection (GtkSheet *sheet,
/* Selection */
-static gboolean gtk_sheet_move_query (GtkSheet *sheet,
- gint row, gint column);
-static void gtk_sheet_real_select_range (GtkSheet * sheet,
- const GtkSheetRange * range);
-static void gtk_sheet_real_unselect_range (GtkSheet * sheet,
- const GtkSheetRange * range);
+static void gtk_sheet_real_select_range (GtkSheet *sheet,
+ const GtkSheetRange *range);
+static void gtk_sheet_real_unselect_range (GtkSheet *sheet,
+ const GtkSheetRange *range);
static void gtk_sheet_extend_selection (GtkSheet *sheet,
gint row, gint column);
static void gtk_sheet_new_selection (GtkSheet *sheet,
GtkSheetRange *range);
static void gtk_sheet_draw_border (GtkSheet *sheet,
GtkSheetRange range);
-static void gtk_sheet_draw_corners (GtkSheet *sheet,
- GtkSheetRange range);
-
/* Active Cell handling */
static void gtk_sheet_entry_changed (GtkWidget *widget,
gpointer data);
-static void gtk_sheet_deactivate_cell (GtkSheet *sheet);
-static void gtk_sheet_hide_active_cell (GtkSheet *sheet);
-static gboolean gtk_sheet_activate_cell (GtkSheet *sheet,
- gint row, gint col);
-static void gtk_sheet_draw_active_cell (GtkSheet *sheet);
-static void gtk_sheet_show_active_cell (GtkSheet *sheet);
-static void gtk_sheet_click_cell (GtkSheet *sheet,
+static void gtk_sheet_hide_entry_widget (GtkSheet *sheet);
+static void change_active_cell (GtkSheet *sheet,
+ gint row, gint col);
+static gboolean gtk_sheet_draw_active_cell (GtkSheet *sheet);
+static void gtk_sheet_show_entry_widget (GtkSheet *sheet);
+static gboolean gtk_sheet_click_cell (GtkSheet *sheet,
gint row,
- gint column,
- gboolean *veto);
+ gint column);
-/* Backing Pixmap */
-static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet,
- guint width, guint height);
-static void gtk_sheet_draw_backing_pixmap (GtkSheet *sheet,
- GtkSheetRange range);
/* Scrollbars */
-static void adjust_scrollbars (GtkSheet * sheet);
-static void vadjustment_value_changed (GtkAdjustment * adjustment,
+static void adjust_scrollbars (GtkSheet *sheet);
+static void vadjustment_value_changed (GtkAdjustment *adjustment,
gpointer data);
-static void hadjustment_value_changed (GtkAdjustment * adjustment,
+static void hadjustment_value_changed (GtkAdjustment *adjustment,
gpointer data);
-static void draw_xor_vline (GtkSheet * sheet);
-static void draw_xor_hline (GtkSheet * sheet);
+static void draw_xor_vline (GtkSheet *sheet);
+static void draw_xor_hline (GtkSheet *sheet);
static void draw_xor_rectangle (GtkSheet *sheet,
GtkSheetRange range);
-static guint new_column_width (GtkSheet * sheet,
- gint column,
- gint * x);
-static guint new_row_height (GtkSheet * sheet,
- gint row,
- gint * y);
/* Sheet Button */
static void create_global_button (GtkSheet *sheet);
static void create_sheet_entry (GtkSheet *sheet);
static void gtk_sheet_size_allocate_entry (GtkSheet *sheet);
-static void gtk_sheet_entry_set_max_size (GtkSheet *sheet);
/* Sheet button gadgets */
-static void size_allocate_column_title_buttons (GtkSheet * sheet);
-static void size_allocate_row_title_buttons (GtkSheet * sheet);
+static void draw_column_title_buttons (GtkSheet *sheet);
+static void draw_row_title_buttons (GtkSheet *sheet);
static void size_allocate_global_button (GtkSheet *sheet);
const GtkSheetButton *button,
GtkRequisition *requisition);
-/* Attributes routines */
-static void init_attributes (const GtkSheet *sheet, gint col,
- GtkSheetCellAttr *attributes);
-
-
-/* Memory allocation routines */
-static void gtk_sheet_real_range_clear (GtkSheet *sheet,
- const GtkSheetRange *range);
-
static void gtk_sheet_real_cell_clear (GtkSheet *sheet,
gint row,
gint column);
-/* Container Functions */
-static void gtk_sheet_remove (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_sheet_realize_child (GtkSheet *sheet,
- GtkSheetChild *child);
-static void gtk_sheet_position_child (GtkSheet *sheet,
- GtkSheetChild *child);
-static void gtk_sheet_position_children (GtkSheet *sheet);
-static void gtk_sheet_child_show (GtkSheetChild *child);
-static void gtk_sheet_child_hide (GtkSheetChild *child);
-static void gtk_sheet_column_size_request (GtkSheet *sheet,
- gint col,
- guint *requisition);
static void gtk_sheet_row_size_request (GtkSheet *sheet,
gint row,
guint *requisition);
/* Signals */
-
-extern void
-_gtkextra_signal_emit (GtkObject *object, guint signal_id, ...);
-
enum
{
SELECT_ROW,
RESIZE_RANGE,
MOVE_RANGE,
TRAVERSE,
- DEACTIVATE,
ACTIVATE,
- CHANGED,
LAST_SIGNAL
};
(GInstanceInitFunc) gtk_sheet_init,
NULL,
};
+
sheet_type =
- g_type_register_static (GTK_TYPE_CONTAINER, "GtkSheet",
+ g_type_register_static (GTK_TYPE_BIN, "GtkSheet",
&sheet_info, 0);
}
return sheet_type;
}
+\f
+
static GtkSheetRange*
gtk_sheet_range_copy (const GtkSheetRange *range)
{
return sheet_range_type;
}
+static GtkSheetCell*
+gtk_sheet_cell_copy (const GtkSheetCell *cell)
+{
+ GtkSheetCell *new_cell;
+
+ g_return_val_if_fail (cell != NULL, NULL);
+
+ new_cell = g_new (GtkSheetCell, 1);
+
+ *new_cell = *cell;
+
+ return new_cell;
+}
+
+static void
+gtk_sheet_cell_free (GtkSheetCell *cell)
+{
+ g_return_if_fail (cell != NULL);
+
+ g_free (cell);
+}
+
+GType
+gtk_sheet_cell_get_type (void)
+{
+ static GType sheet_cell_type = 0;
+
+ if (!sheet_cell_type)
+ {
+ sheet_cell_type =
+ g_boxed_type_register_static ("GtkSheetCell",
+ (GBoxedCopyFunc) gtk_sheet_cell_copy,
+ (GBoxedFreeFunc) gtk_sheet_cell_free);
+ }
-static void column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data);
+ return sheet_cell_type;
+}
+\f
/* Properties */
enum
{
PROP_0,
- PROP_ROW_GEO,
- PROP_COL_GEO,
+ PROP_VAXIS,
+ PROP_HAXIS,
PROP_MODEL
};
static void
-gtk_sheet_set_row_geometry (GtkSheet *sheet, GSheetRow *geo)
+gtk_sheet_set_horizontal_axis (GtkSheet *sheet, PsppireAxis *a)
{
- if ( sheet->row_geometry ) g_object_unref (sheet->row_geometry);
+ if ( sheet->haxis )
+ g_object_unref (sheet->haxis);
- sheet->row_geometry = geo;
+ sheet->haxis = a;
- if ( sheet->row_geometry ) g_object_ref (sheet->row_geometry);
+ if ( sheet->haxis )
+ g_object_ref (sheet->haxis);
}
static void
-gtk_sheet_set_column_geometry (GtkSheet *sheet, GSheetColumn *geo)
+gtk_sheet_set_vertical_axis (GtkSheet *sheet, PsppireAxis *a)
{
- if ( sheet->column_geometry ) g_object_unref (sheet->column_geometry);
+ if ( sheet->vaxis )
+ g_object_unref (sheet->vaxis);
- sheet->column_geometry = geo;
+ sheet->vaxis = a;
- if ( sheet->column_geometry ) g_object_ref (sheet->column_geometry);
+ if ( sheet->vaxis )
+ g_object_ref (sheet->vaxis);
}
switch (prop_id)
{
- case PROP_ROW_GEO:
- gtk_sheet_set_row_geometry (sheet, g_value_get_pointer (value));
+ case PROP_VAXIS:
+ gtk_sheet_set_vertical_axis (sheet, g_value_get_pointer (value));
break;
- case PROP_COL_GEO:
- gtk_sheet_set_column_geometry (sheet, g_value_get_pointer (value));
- if ( sheet->column_geometry)
- g_signal_connect (sheet->column_geometry, "columns_changed",
- G_CALLBACK (column_titles_changed), sheet);
+ case PROP_HAXIS:
+ gtk_sheet_set_horizontal_axis (sheet, g_value_get_pointer (value));
break;
case PROP_MODEL:
gtk_sheet_set_model (sheet, g_value_get_pointer (value));
switch (prop_id)
{
- case PROP_ROW_GEO:
- g_value_set_pointer (value, sheet->row_geometry);
+ case PROP_VAXIS:
+ g_value_set_pointer (value, sheet->vaxis);
break;
- case PROP_COL_GEO:
- g_value_set_pointer (value, sheet->column_geometry);
+ case PROP_HAXIS:
+ g_value_set_pointer (value, sheet->haxis);
break;
case PROP_MODEL:
g_value_set_pointer (value, sheet->model);
static void
-gtk_sheet_class_init (GtkSheetClass * klass)
+gtk_sheet_class_init (GtkSheetClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *row_geo_spec ;
- GParamSpec *col_geo_spec ;
+ GParamSpec *haxis_spec ;
+ GParamSpec *vaxis_spec ;
GParamSpec *model_spec ;
- GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
- GtkContainerClass *container_class = (GtkContainerClass *) klass;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- gtkextra_VOID__INT_POINTER,
+ psppire_marshal_VOID__INT_POINTER,
G_TYPE_NONE,
2,
G_TYPE_INT,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- gtkextra_VOID__INT_POINTER,
+ psppire_marshal_VOID__INT_POINTER,
G_TYPE_NONE,
2,
G_TYPE_INT,
G_SIGNAL_RUN_LAST,
offsetof (GtkSheetClass, resize_range),
NULL, NULL,
- gtkextra_VOID__BOXED_BOXED,
+ psppire_marshal_VOID__BOXED_BOXED,
G_TYPE_NONE,
2,
GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE
G_SIGNAL_RUN_LAST,
offsetof (GtkSheetClass, move_range),
NULL, NULL,
- gtkextra_VOID__BOXED_BOXED,
+ psppire_marshal_VOID__BOXED_BOXED,
G_TYPE_NONE,
2,
GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE
G_SIGNAL_RUN_LAST,
offsetof (GtkSheetClass, traverse),
NULL, NULL,
- gtkextra_BOOLEAN__INT_INT_POINTER_POINTER,
- G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT,
- G_TYPE_POINTER, G_TYPE_POINTER);
-
+ psppire_marshal_BOOLEAN__BOXED_POINTER,
+ G_TYPE_BOOLEAN, 2,
+ GTK_TYPE_SHEET_CELL,
+ G_TYPE_POINTER);
- sheet_signals[DEACTIVATE] =
- g_signal_new ("deactivate",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- offsetof (GtkSheetClass, deactivate),
- NULL, NULL,
- gtkextra_VOID__INT_INT,
- G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
sheet_signals[ACTIVATE] =
g_signal_new ("activate",
G_SIGNAL_RUN_LAST,
offsetof (GtkSheetClass, activate),
NULL, NULL,
- gtkextra_BOOLEAN__INT_INT,
- G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT);
-
- sheet_signals[CHANGED] =
- g_signal_new ("changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- offsetof (GtkSheetClass, changed),
- NULL, NULL,
- gtkextra_VOID__INT_INT,
- G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+ psppire_marshal_VOID__INT_INT_INT_INT,
+ G_TYPE_NONE, 4,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_INT, G_TYPE_INT);
widget_class->set_scroll_adjustments_signal =
g_signal_new ("set-scroll-adjustments",
G_SIGNAL_RUN_LAST,
offsetof (GtkSheetClass, set_scroll_adjustments),
NULL, NULL,
- gtkextra_VOID__OBJECT_OBJECT,
+ psppire_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
container_class->add = NULL;
- container_class->remove = gtk_sheet_remove;
+ container_class->remove = NULL;
container_class->forall = gtk_sheet_forall;
object_class->dispose = gtk_sheet_dispose;
object_class->finalize = gtk_sheet_finalize;
- row_geo_spec =
- g_param_spec_pointer ("row-geometry",
- "Row Geometry",
- "A pointer to the model of the row geometry",
+ vaxis_spec =
+ g_param_spec_pointer ("vertical-axis",
+ "Vertical Axis",
+ "A pointer to the PsppireAxis object for the rows",
G_PARAM_READABLE | G_PARAM_WRITABLE );
- col_geo_spec =
- g_param_spec_pointer ("column-geometry",
- "Column Geometry",
- "A pointer to the model of the column geometry",
+ haxis_spec =
+ g_param_spec_pointer ("horizontal-axis",
+ "Horizontal Axis",
+ "A pointer to the PsppireAxis object for the columns",
G_PARAM_READABLE | G_PARAM_WRITABLE );
model_spec =
object_class->get_property = gtk_sheet_get_property;
g_object_class_install_property (object_class,
- PROP_ROW_GEO,
- row_geo_spec);
+ PROP_VAXIS,
+ vaxis_spec);
g_object_class_install_property (object_class,
- PROP_COL_GEO,
- col_geo_spec);
+ PROP_HAXIS,
+ haxis_spec);
g_object_class_install_property (object_class,
PROP_MODEL,
widget_class->button_press_event = gtk_sheet_button_press;
widget_class->button_release_event = gtk_sheet_button_release;
widget_class->motion_notify_event = gtk_sheet_motion;
+ widget_class->enter_notify_event = gtk_sheet_crossing_notify;
+ widget_class->leave_notify_event = gtk_sheet_crossing_notify;
widget_class->key_press_event = gtk_sheet_key_press;
widget_class->expose_event = gtk_sheet_expose;
widget_class->size_request = gtk_sheet_size_request;
klass->resize_range = NULL;
klass->move_range = NULL;
klass->traverse = NULL;
- klass->deactivate = NULL;
klass->activate = NULL;
klass->changed = NULL;
}
gtk_sheet_init (GtkSheet *sheet)
{
sheet->model = NULL;
- sheet->column_geometry = NULL;
- sheet->row_geometry = NULL;
-
- sheet->children = NULL;
+ sheet->haxis = NULL;
+ sheet->vaxis = NULL;
sheet->flags = 0;
sheet->selection_mode = GTK_SELECTION_NONE;
- sheet->freeze_count = 0;
sheet->state = GTK_SHEET_NORMAL;
GTK_WIDGET_UNSET_FLAGS (sheet, GTK_NO_WINDOW);
sheet->column_title_area.x = 0;
sheet->column_title_area.y = 0;
sheet->column_title_area.width = 0;
- sheet->column_title_area.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet));
+ sheet->column_title_area.height = DEFAULT_ROW_HEIGHT;
sheet->row_title_window = NULL;
sheet->row_title_area.x = 0;
sheet->selection_cell.row = 0;
sheet->selection_cell.col = 0;
- sheet->pixmap = NULL;
-
sheet->range.row0 = 0;
sheet->range.rowi = 0;
sheet->range.col0 = 0;
sheet->state = GTK_SHEET_NORMAL;
sheet->sheet_window = NULL;
- sheet->sheet_window_width = 0;
- sheet->sheet_window_height = 0;
sheet->entry_widget = NULL;
- sheet->entry_container = NULL;
+ sheet->entry_handler_id = 0;
sheet->button = NULL;
- sheet->hoffset = 0;
- sheet->voffset = 0;
-
sheet->hadjustment = NULL;
sheet->vadjustment = NULL;
- sheet->cursor_drag = gdk_cursor_new (GDK_PLUS);
+ sheet->cursor_drag = NULL;
+
sheet->xor_gc = NULL;
sheet->fg_gc = NULL;
sheet->bg_gc = NULL;
sheet->x_drag = 0;
sheet->y_drag = 0;
- gdk_color_parse ("white", &sheet->bg_color);
- gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->bg_color, FALSE,
- TRUE);
- gdk_color_parse ("gray", &sheet->grid_color);
- gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->grid_color, FALSE,
- TRUE);
-
sheet->show_grid = TRUE;
sheet->motion_timer = 0;
- sheet->columns_resizable = TRUE;
- sheet->rows_resizable = TRUE;
-
sheet->row_titles_visible = TRUE;
sheet->row_title_area.width = DEFAULT_COLUMN_WIDTH;
sheet->column_titles_visible = TRUE;
- sheet->autoscroll = TRUE;
- sheet->justify_entry = TRUE;
/* create sheet entry */
- sheet->entry_type = 0;
+ sheet->entry_type = GTK_TYPE_ENTRY;
create_sheet_entry (sheet);
/* create global selection button */
gint n_columns,
gpointer data)
{
- gint i;
GtkSheet *sheet = GTK_SHEET (data);
GtkSheetRange range;
*/
range.col0 = first_column;
range.row0 = 0;
- range.coli = xxx_column_count (sheet) - 1;
- range.rowi = yyy_row_count (sheet) - 1;
+ range.coli = psppire_axis_unit_count (sheet->haxis) - 1;
+ range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1;
adjust_scrollbars (sheet);
if (sheet->active_cell.col >= model_columns)
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row, model_columns - 1);
+ change_active_cell (sheet, sheet->active_cell.row, model_columns - 1);
- for (i = first_column; i <= MAX_VISIBLE_COLUMN (sheet); i++)
- gtk_sheet_column_title_button_draw (sheet, i);
+ draw_column_title_buttons_range (sheet,
+ first_column, max_visible_column (sheet));
gtk_sheet_range_draw (sheet, &range);
}
rows_inserted_deleted_callback (GSheetModel *model, gint first_row,
gint n_rows, gpointer data)
{
- gint i;
GtkSheet *sheet = GTK_SHEET (data);
GtkSheetRange range;
*/
range.row0 = first_row;
range.col0 = 0;
- range.rowi = yyy_row_count (sheet) - 1;
- range.coli = xxx_column_count (sheet) - 1;
+ range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1;
+ range.coli = psppire_axis_unit_count (sheet->haxis) - 1;
adjust_scrollbars (sheet);
if (sheet->active_cell.row >= model_rows)
- gtk_sheet_activate_cell (sheet, model_rows - 1, sheet->active_cell.col);
+ change_active_cell (sheet, model_rows - 1, sheet->active_cell.col);
- for (i = first_row; i <= MAX_VISIBLE_ROW (sheet); i++)
- gtk_sheet_row_title_button_draw (sheet, i);
+ draw_row_title_buttons_range (sheet, first_row, max_visible_row (sheet));
gtk_sheet_range_draw (sheet, &range);
}
range.rowi = rowi;
range.coli = coli;
- if ( MAX_VISIBLE_ROW (sheet) >
- g_sheet_model_get_row_count (sheet->model)
- ||
- MAX_VISIBLE_COLUMN (sheet) >
- g_sheet_model_get_column_count (sheet->model))
- {
- gtk_sheet_move_query (sheet, 0, 0);
- }
+ if ( !GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ return;
if ( ( row0 < 0 && col0 < 0 ) || ( rowi < 0 && coli < 0 ) )
{
- gint i;
gtk_sheet_range_draw (sheet, NULL);
adjust_scrollbars (sheet);
- for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++)
- gtk_sheet_row_title_button_draw (sheet, i);
+ draw_row_title_buttons_range (sheet, min_visible_row (sheet),
+ max_visible_row (sheet));
- for (i = MIN_VISIBLE_COLUMN (sheet);
- i <= MAX_VISIBLE_COLUMN (sheet); i++)
- gtk_sheet_column_title_button_draw (sheet, i);
+ draw_column_title_buttons_range (sheet, min_visible_column (sheet),
+ max_visible_column (sheet));
return;
}
else if ( row0 < 0 || rowi < 0 )
{
- range.row0 = MIN_VISIBLE_ROW (sheet);
- range.rowi = MAX_VISIBLE_ROW (sheet);
+ range.row0 = min_visible_row (sheet);
+ range.rowi = max_visible_row (sheet);
}
else if ( col0 < 0 || coli < 0 )
{
- range.col0 = MIN_VISIBLE_COLUMN (sheet);
- range.coli = MAX_VISIBLE_COLUMN (sheet);
+ range.col0 = min_visible_column (sheet);
+ range.coli = max_visible_column (sheet);
}
gtk_sheet_range_draw (sheet, &range);
* Returns: the new sheet widget
*/
GtkWidget *
-gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo, GSheetModel *model)
+gtk_sheet_new (GSheetModel *model)
{
GtkWidget *widget = g_object_new (GTK_TYPE_SHEET,
- "row-geometry", vgeo,
- "column-geometry", hgeo,
"model", model,
NULL);
return widget;
}
-/* Call back for when the column titles have changed.
- FIRST is the first column changed.
- N_COLUMNS is the number of columns which have changed, or - 1, which
- indicates that the column has changed to its right - most extremity
-*/
-static void
-column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data)
-{
- GtkSheet *sheet = GTK_SHEET (data);
- gboolean extremity = FALSE;
-
- if ( n_columns == -1 )
- {
- extremity = TRUE;
- n_columns = xxx_column_count (sheet) - 1 ;
- }
-
- if (!GTK_SHEET_IS_FROZEN (sheet))
- {
- gint i;
- for ( i = first ; i <= first + n_columns ; ++i )
- {
- gtk_sheet_column_title_button_draw (sheet, i);
- g_signal_emit (sheet, sheet_signals[CHANGED], 0, -1, i);
- }
- }
-
- if ( extremity)
- gtk_sheet_column_title_button_draw (sheet, -1);
-
-}
-
void
gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type)
{
state = sheet->state;
if (sheet->state == GTK_SHEET_NORMAL)
- gtk_sheet_hide_active_cell (sheet);
+ gtk_sheet_hide_entry_widget (sheet);
sheet->entry_type = entry_type;
if (state == GTK_SHEET_NORMAL)
{
- gtk_sheet_show_active_cell (sheet);
- g_signal_connect (gtk_sheet_get_entry (sheet),
- "changed",
- G_CALLBACK (gtk_sheet_entry_changed),
- sheet);
+ gtk_sheet_show_entry_widget (sheet);
}
+
}
void
sheet->show_grid = show;
- if (!GTK_SHEET_IS_FROZEN (sheet))
- gtk_sheet_range_draw (sheet, NULL);
+ gtk_sheet_range_draw (sheet, NULL);
}
gboolean
return sheet->show_grid;
}
-void
-gtk_sheet_set_background (GtkSheet *sheet, GdkColor *color)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (!color)
- {
- gdk_color_parse ("white", &sheet->bg_color);
- gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->bg_color, FALSE, TRUE);
- }
- else
- sheet->bg_color = *color;
-
- if (!GTK_SHEET_IS_FROZEN (sheet))
- gtk_sheet_range_draw (sheet, NULL);
-}
-
-void
-gtk_sheet_set_grid (GtkSheet *sheet, GdkColor *color)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (!color)
- {
- gdk_color_parse ("black", &sheet->grid_color);
- gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->grid_color, FALSE, TRUE);
- }
- else
- sheet->grid_color = *color;
-
- if (!GTK_SHEET_IS_FROZEN (sheet))
- gtk_sheet_range_draw (sheet, NULL);
-}
-
-guint
-gtk_sheet_get_columns_count (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, 0);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
-
- return xxx_column_count (sheet);
-}
-
-guint
-gtk_sheet_get_rows_count (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, 0);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
-
- return yyy_row_count (sheet);
-}
-
-gint
-gtk_sheet_get_state (GtkSheet *sheet)
+guint
+gtk_sheet_get_columns_count (GtkSheet *sheet)
{
g_return_val_if_fail (sheet != NULL, 0);
g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
- return (sheet->state);
-}
-
-void
-gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (GTK_WIDGET_REALIZED (sheet))
- gtk_sheet_real_unselect_range (sheet, NULL);
-
- sheet->selection_mode = mode;
-}
-
-void
-gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- sheet->autoresize = autoresize;
-}
-
-gboolean
-gtk_sheet_autoresize (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
-
- return sheet->autoresize;
-}
-
-static void
-gtk_sheet_set_column_width (GtkSheet * sheet,
- gint column,
- guint width);
-
-
-static void
-gtk_sheet_autoresize_column (GtkSheet *sheet, gint column)
-{
- gint text_width = 0;
- gint row;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
- if (column >= xxx_column_count (sheet) || column < 0) return;
-
- for (row = 0; row < yyy_row_count (sheet); row++)
- {
- gchar *text = gtk_sheet_cell_get_text (sheet, row, column);
- if (text && strlen (text) > 0)
- {
- GtkSheetCellAttr attributes;
-
- gtk_sheet_get_attributes (sheet, row, column, &attributes);
- if (attributes.is_visible)
- {
- gint width = STRING_WIDTH (GTK_WIDGET (sheet),
- attributes.font_desc,
- text)
- + 2 * CELLOFFSET + attributes.border.width;
- text_width = MAX (text_width, width);
- }
- }
- dispose_string (sheet, text);
- }
-
- if (text_width > xxx_column_width (sheet, column) )
- {
- gtk_sheet_set_column_width (sheet, column, text_width);
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING);
- }
-}
-
-
-void
-gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- sheet->autoscroll = autoscroll;
-}
-
-gboolean
-gtk_sheet_autoscroll (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
-
- return sheet->autoscroll;
-}
-
-
-void
-gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- sheet->justify_entry = justify;
-}
-
-gboolean
-gtk_sheet_justify_entry (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
-
- return sheet->justify_entry;
-}
-
-
-
-void
-gtk_sheet_freeze (GtkSheet *sheet)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- sheet->freeze_count++;
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IS_FROZEN);
-}
-
-void
-gtk_sheet_thaw (GtkSheet *sheet)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (sheet->freeze_count == 0) return;
-
- sheet->freeze_count--;
- if (sheet->freeze_count > 0) return;
-
- adjust_scrollbars (sheet);
-
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN);
-
- sheet->old_vadjustment = -1.;
- sheet->old_hadjustment = -1.;
-
- if (sheet->hadjustment)
- g_signal_emit_by_name (sheet->hadjustment,
- "value_changed");
- if (sheet->vadjustment)
- g_signal_emit_by_name (sheet->vadjustment,
- "value_changed");
-
- if (sheet->state == GTK_STATE_NORMAL)
- if (sheet->entry_widget && GTK_WIDGET_MAPPED (sheet->entry_widget))
- {
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
- sheet->active_cell.col);
- }
-
-}
-
-void
-gtk_sheet_set_row_titles_width (GtkSheet *sheet, guint width)
-{
- if (width < COLUMN_MIN_WIDTH) return;
-
- sheet->row_title_area.width = width;
-
- adjust_scrollbars (sheet);
-
- sheet->old_hadjustment = -1.;
- if (sheet->hadjustment)
- g_signal_emit_by_name (sheet->hadjustment,
- "value_changed");
- size_allocate_global_button (sheet);
+ return psppire_axis_unit_count (sheet->haxis);
}
-void
-gtk_sheet_set_column_titles_height (GtkSheet *sheet, guint height)
-{
- if (height < DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))) return;
-
- sheet->column_title_area.height = height;
-
- adjust_scrollbars (sheet);
+static void set_column_width (GtkSheet *sheet,
+ gint column,
+ gint width);
- sheet->old_vadjustment = -1.;
- if (sheet->vadjustment)
- g_signal_emit_by_name (sheet->vadjustment,
- "value_changed");
- size_allocate_global_button (sheet);
-}
void
gtk_sheet_show_column_titles (GtkSheet *sheet)
{
- gint col;
-
if (sheet->column_titles_visible) return;
sheet->column_titles_visible = TRUE;
+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ return;
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
- {
- gdk_window_show (sheet->column_title_window);
- gdk_window_move_resize (sheet->column_title_window,
- sheet->column_title_area.x,
- sheet->column_title_area.y,
- sheet->column_title_area.width,
- sheet->column_title_area.height);
+ gdk_window_show (sheet->column_title_window);
+ gdk_window_move_resize (sheet->column_title_window,
+ sheet->column_title_area.x,
+ sheet->column_title_area.y,
+ sheet->column_title_area.width,
+ sheet->column_title_area.height);
- for (col = MIN_VISIBLE_COLUMN (sheet);
- col <= MAX_VISIBLE_COLUMN (sheet);
- col++)
- {
- GtkSheetButton *button = xxx_column_button (sheet, col);
- GtkSheetChild *child = button->child;
- if (child)
- gtk_sheet_child_show (child);
- gtk_sheet_button_free (button);
- }
- adjust_scrollbars (sheet);
- }
+ adjust_scrollbars (sheet);
- sheet->old_vadjustment = -1.;
if (sheet->vadjustment)
g_signal_emit_by_name (sheet->vadjustment,
"value_changed");
void
gtk_sheet_show_row_titles (GtkSheet *sheet)
{
- gint row;
-
if (sheet->row_titles_visible) return;
sheet->row_titles_visible = TRUE;
sheet->row_title_area.width,
sheet->row_title_area.height);
- for (row = MIN_VISIBLE_ROW (sheet);
- row <= MAX_VISIBLE_ROW (sheet);
- row++)
- {
- const GtkSheetButton *button = yyy_row_button (sheet, row);
- GtkSheetChild *child = button->child;
-
- if (child)
- {
- gtk_sheet_child_show (child);
- }
- }
adjust_scrollbars (sheet);
}
- sheet->old_hadjustment = -1.;
if (sheet->hadjustment)
g_signal_emit_by_name (sheet->hadjustment,
"value_changed");
void
gtk_sheet_hide_column_titles (GtkSheet *sheet)
{
- gint col;
-
if (!sheet->column_titles_visible) return;
sheet->column_titles_visible = FALSE;
if (GTK_WIDGET_VISIBLE (sheet->button))
gtk_widget_hide (sheet->button);
- for (col = MIN_VISIBLE_COLUMN (sheet);
- col <= MAX_VISIBLE_COLUMN (sheet);
- col++)
- {
- GtkSheetButton *button = xxx_column_button (sheet, col);
- GtkSheetChild *child = button->child;
- if (child)
- gtk_sheet_child_hide (child);
- gtk_sheet_button_free (button);
- }
adjust_scrollbars (sheet);
}
- sheet->old_vadjustment = -1.;
if (sheet->vadjustment)
g_signal_emit_by_name (sheet->vadjustment,
"value_changed");
void
gtk_sheet_hide_row_titles (GtkSheet *sheet)
{
- gint row;
-
if (!sheet->row_titles_visible) return;
sheet->row_titles_visible = FALSE;
-
if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
{
if (sheet->row_title_window)
gdk_window_hide (sheet->row_title_window);
+
if (GTK_WIDGET_VISIBLE (sheet->button))
gtk_widget_hide (sheet->button);
- for (row = MIN_VISIBLE_ROW (sheet);
- row <= MAX_VISIBLE_ROW (sheet);
- row++)
- {
- const GtkSheetButton *button = yyy_row_button (sheet, row);
- GtkSheetChild *child = button->child;
- if (child)
- gtk_sheet_child_hide (child);
- }
adjust_scrollbars (sheet);
}
- sheet->old_hadjustment = -1.;
if (sheet->hadjustment)
g_signal_emit_by_name (sheet->hadjustment,
"value_changed");
}
-gboolean
-gtk_sheet_column_titles_visible (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
- return sheet->column_titles_visible;
-}
-
-gboolean
-gtk_sheet_row_titles_visible (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
- return sheet->row_titles_visible;
-}
+/* Scroll the sheet so that the cell ROW, COLUMN is visible.
+ If {ROW,COL}_ALIGN is zero, then the cell will be placed
+ at the {top,left} of the sheet. If it's 1, then it'll
+ be placed at the {bottom,right}.
+ ROW or COL may be -1, in which case scrolling in that dimension
+ does not occur.
+ */
void
gtk_sheet_moveto (GtkSheet *sheet,
gint row,
- gint column,
+ gint col,
gfloat row_align,
gfloat col_align)
{
- gint x, y;
- guint width, height;
- gint adjust;
- gint min_row, min_col;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
- g_return_if_fail (sheet->hadjustment != NULL);
- g_return_if_fail (sheet->vadjustment != NULL);
-
- if (row < 0 || row >= yyy_row_count (sheet))
- return;
- if (column < 0 || column >= xxx_column_count (sheet))
- return;
-
- height = sheet->sheet_window_height;
- width = sheet->sheet_window_width;
-
- /* adjust vertical scrollbar */
- if (row >= 0 && row_align >= 0.0)
- {
- y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset
- - (gint) ( row_align * height + (1.0 - row_align)
- * yyy_row_height (sheet, row));
-
- /* This forces the sheet to scroll when you don't see the entire cell */
- min_row = row;
- adjust = 0;
- if (row_align >= 1.0)
- {
- while (min_row >= 0 && min_row > MIN_VISIBLE_ROW (sheet))
- {
- if (yyy_row_is_visible (sheet, min_row))
- adjust += yyy_row_height (sheet, min_row);
+ gint width, height;
- if (adjust >= height)
- {
- break;
- }
- min_row--;
- }
- min_row = MAX (min_row, 0);
+ g_return_if_fail (row_align >= 0);
+ g_return_if_fail (col_align >= 0);
- min_row ++;
+ g_return_if_fail (row_align <= 1);
+ g_return_if_fail (col_align <= 1);
- y = ROW_TOP_YPIXEL (sheet, min_row) - sheet->voffset +
- yyy_row_height (sheet, min_row) - 1;
- }
+ g_return_if_fail (col <
+ psppire_axis_unit_count (sheet->haxis));
+ g_return_if_fail (row <
+ psppire_axis_unit_count (sheet->vaxis));
- if (y < 0)
- sheet->vadjustment->value = 0.0;
- else
- sheet->vadjustment->value = y;
+ gdk_drawable_get_size (sheet->sheet_window, &width, &height);
- sheet->old_vadjustment = -1.;
- g_signal_emit_by_name (sheet->vadjustment,
- "value_changed");
- }
+ if (row >= 0)
+ {
+ gint y = psppire_axis_start_pixel (sheet->vaxis, row);
- /* adjust horizontal scrollbar */
- if (column >= 0 && col_align >= 0.0)
- {
- x = COLUMN_LEFT_XPIXEL (sheet, column) - sheet->hoffset
- - (gint) ( col_align*width + (1.0 - col_align)*
- xxx_column_width (sheet, column));
-
- /* This forces the sheet to scroll when you don't see the entire cell */
- min_col = column;
- adjust = 0;
- if (col_align == 1.0)
- {
- while (min_col >= 0 && min_col > MIN_VISIBLE_COLUMN (sheet))
- {
- if (xxx_column_is_visible (sheet, min_col))
- adjust += xxx_column_width (sheet, min_col);
+ gtk_adjustment_set_value (sheet->vadjustment, y - height * row_align);
+ }
- if (adjust >= width)
- {
- break;
- }
- min_col--;
- }
- min_col = MAX (min_col, 0);
- x = COLUMN_LEFT_XPIXEL (sheet, min_col) - sheet->hoffset +
- xxx_column_width (sheet, min_col) - 1;
- }
- if (x < 0)
- sheet->hadjustment->value = 0.0;
- else
- sheet->hadjustment->value = x;
+ if (col >= 0)
+ {
+ gint x = psppire_axis_start_pixel (sheet->haxis, col);
- sheet->old_vadjustment = -1.;
- g_signal_emit_by_name (sheet->hadjustment,
- "value_changed");
- }
+ gtk_adjustment_set_value (sheet->hadjustment, x - width * col_align);
+ }
}
void
-gtk_sheet_columns_set_resizable (GtkSheet *sheet, gboolean resizable)
+gtk_sheet_select_row (GtkSheet *sheet, gint row)
{
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet));
- sheet->columns_resizable = resizable;
-}
+ if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis))
+ return;
-gboolean
-gtk_sheet_columns_resizable (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
+ if (sheet->state != GTK_SHEET_NORMAL)
+ gtk_sheet_real_unselect_range (sheet, NULL);
+
+ sheet->state = GTK_SHEET_ROW_SELECTED;
+ sheet->range.row0 = row;
+ sheet->range.col0 = 0;
+ sheet->range.rowi = row;
+ sheet->range.coli = psppire_axis_unit_count (sheet->haxis) - 1;
+ sheet->active_cell.row = row;
+ sheet->active_cell.col = 0;
- return sheet->columns_resizable;
+ g_signal_emit (sheet, sheet_signals[SELECT_ROW], 0, row);
+ gtk_sheet_real_select_range (sheet, NULL);
}
void
-gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable)
+gtk_sheet_select_column (GtkSheet *sheet, gint column)
{
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet));
- sheet->rows_resizable = resizable;
-}
-
-gboolean
-gtk_sheet_rows_resizable (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
-
- return sheet->rows_resizable;
-}
-
-
-void
-gtk_sheet_select_row (GtkSheet * sheet,
- gint row)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (row < 0 || row >= yyy_row_count (sheet))
- return;
-
- if (sheet->state != GTK_SHEET_NORMAL)
- gtk_sheet_real_unselect_range (sheet, NULL);
- else
- gtk_sheet_deactivate_cell (sheet);
-
- sheet->state = GTK_SHEET_ROW_SELECTED;
- sheet->range.row0 = row;
- sheet->range.col0 = 0;
- sheet->range.rowi = row;
- sheet->range.coli = xxx_column_count (sheet) - 1;
- sheet->active_cell.row = row;
- sheet->active_cell.col = 0;
-
- g_signal_emit (sheet, sheet_signals[SELECT_ROW], 0, row);
- gtk_sheet_real_select_range (sheet, NULL);
-}
-
-
-void
-gtk_sheet_select_column (GtkSheet * sheet, gint column)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (column < 0 || column >= xxx_column_count (sheet))
+ if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis))
return;
if (sheet->state != GTK_SHEET_NORMAL)
gtk_sheet_real_unselect_range (sheet, NULL);
- else
- gtk_sheet_deactivate_cell (sheet);
-
sheet->state = GTK_SHEET_COLUMN_SELECTED;
sheet->range.row0 = 0;
sheet->range.col0 = column;
- sheet->range.rowi = yyy_row_count (sheet) - 1;
+ sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1;
sheet->range.coli = column;
sheet->active_cell.row = 0;
sheet->active_cell.col = column;
static gboolean
-gtk_sheet_range_isvisible (const GtkSheet * sheet,
- GtkSheetRange range)
+gtk_sheet_range_isvisible (const GtkSheet *sheet,
+ const GtkSheetRange *range)
{
g_return_val_if_fail (sheet != NULL, FALSE);
- if (range.row0 < 0 || range.row0 >= yyy_row_count (sheet))
+ if (range->row0 < 0 || range->row0 >= psppire_axis_unit_count (sheet->vaxis))
return FALSE;
- if (range.rowi < 0 || range.rowi >= yyy_row_count (sheet))
+ if (range->rowi < 0 || range->rowi >= psppire_axis_unit_count (sheet->vaxis))
return FALSE;
- if (range.col0 < 0 || range.col0 >= xxx_column_count (sheet))
+ if (range->col0 < 0 || range->col0 >= psppire_axis_unit_count (sheet->haxis))
return FALSE;
- if (range.coli < 0 || range.coli >= xxx_column_count (sheet))
+ if (range->coli < 0 || range->coli >= psppire_axis_unit_count (sheet->haxis))
return FALSE;
- if (range.rowi < MIN_VISIBLE_ROW (sheet))
+ if (range->rowi < min_visible_row (sheet))
return FALSE;
- if (range.row0 > MAX_VISIBLE_ROW (sheet))
+ if (range->row0 > max_visible_row (sheet))
return FALSE;
- if (range.coli < MIN_VISIBLE_COLUMN (sheet))
+ if (range->coli < min_visible_column (sheet))
return FALSE;
- if (range.col0 > MAX_VISIBLE_COLUMN (sheet))
+ if (range->col0 > max_visible_column (sheet))
return FALSE;
return TRUE;
}
static gboolean
-gtk_sheet_cell_isvisible (GtkSheet * sheet,
+gtk_sheet_cell_isvisible (GtkSheet *sheet,
gint row, gint column)
{
GtkSheetRange range;
range.rowi = row;
range.coli = column;
- return gtk_sheet_range_isvisible (sheet, range);
+ return gtk_sheet_range_isvisible (sheet, &range);
}
void
g_return_if_fail (GTK_IS_SHEET (sheet)) ;
g_return_if_fail (range != NULL);
- range->row0 = MIN_VISIBLE_ROW (sheet);
- range->col0 = MIN_VISIBLE_COLUMN (sheet);
- range->rowi = MAX_VISIBLE_ROW (sheet);
- range->coli = MAX_VISIBLE_COLUMN (sheet);
+ range->row0 = min_visible_row (sheet);
+ range->col0 = min_visible_column (sheet);
+ range->rowi = max_visible_row (sheet);
+ range->coli = max_visible_column (sheet);
}
-GtkAdjustment *
-gtk_sheet_get_vadjustment (GtkSheet * sheet)
-{
- g_return_val_if_fail (sheet != NULL, NULL);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
-
- return sheet->vadjustment;
-}
-
-GtkAdjustment *
-gtk_sheet_get_hadjustment (GtkSheet * sheet)
-{
- g_return_val_if_fail (sheet != NULL, NULL);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
-
- return sheet->hadjustment;
-}
-void
-gtk_sheet_set_vadjustment (GtkSheet *sheet,
- GtkAdjustment *adjustment)
+static void
+gtk_sheet_set_scroll_adjustments (GtkSheet *sheet,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment)
{
- GtkAdjustment *old_adjustment;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
- if (adjustment)
- g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
-
- if (sheet->vadjustment == adjustment)
- return;
-
- old_adjustment = sheet->vadjustment;
-
- if (sheet->vadjustment)
+ if ( sheet->vadjustment != vadjustment )
{
- g_signal_handlers_disconnect_matched (sheet->vadjustment,
- G_SIGNAL_MATCH_DATA,
- 0, 0, 0, 0,
- sheet);
- g_object_unref (sheet->vadjustment);
- }
-
- sheet->vadjustment = adjustment;
-
- if (sheet->vadjustment)
- {
- g_object_ref (sheet->vadjustment);
- g_object_ref_sink (sheet->vadjustment);
+ if (sheet->vadjustment)
+ g_object_unref (sheet->vadjustment);
+ sheet->vadjustment = vadjustment;
+ g_object_ref (vadjustment);
g_signal_connect (sheet->vadjustment, "value_changed",
G_CALLBACK (vadjustment_value_changed),
sheet);
}
- if (!sheet->vadjustment || !old_adjustment)
- {
- gtk_widget_queue_resize (GTK_WIDGET (sheet));
- return;
- }
-
- sheet->old_vadjustment = sheet->vadjustment->value;
-}
-
-void
-gtk_sheet_set_hadjustment (GtkSheet *sheet,
- GtkAdjustment *adjustment)
-{
- GtkAdjustment *old_adjustment;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
- if (adjustment)
- g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
-
- if (sheet->hadjustment == adjustment)
- return;
-
- old_adjustment = sheet->hadjustment;
-
- if (sheet->hadjustment)
- {
- g_signal_handlers_disconnect_matched (sheet->hadjustment,
- G_SIGNAL_MATCH_DATA,
- 0, 0, 0, 0,
- sheet);
- g_object_unref (sheet->hadjustment);
- }
-
- sheet->hadjustment = adjustment;
-
- if (sheet->hadjustment)
+ if ( sheet->hadjustment != hadjustment )
{
- g_object_ref (sheet->hadjustment);
- g_object_ref_sink (sheet->hadjustment);
+ if (sheet->hadjustment)
+ g_object_unref (sheet->hadjustment);
+ sheet->hadjustment = hadjustment;
+ g_object_ref (hadjustment);
g_signal_connect (sheet->hadjustment, "value_changed",
G_CALLBACK (hadjustment_value_changed),
sheet);
}
-
- if (!sheet->hadjustment || !old_adjustment)
- {
- gtk_widget_queue_resize (GTK_WIDGET (sheet));
- return;
- }
-
- sheet->old_hadjustment = sheet->hadjustment->value;
-}
-
-static void
-gtk_sheet_set_scroll_adjustments (GtkSheet *sheet,
- GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment)
-{
- if (sheet->hadjustment != hadjustment)
- gtk_sheet_set_hadjustment (sheet, hadjustment);
-
- if (sheet->vadjustment != vadjustment)
- gtk_sheet_set_vadjustment (sheet, vadjustment);
}
static void
-gtk_sheet_finalize (GObject * object)
+gtk_sheet_finalize (GObject *object)
{
GtkSheet *sheet;
gtk_sheet_dispose (GObject *object)
{
GtkSheet *sheet = GTK_SHEET (object);
- GList *children;
g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_SHEET (object));
sheet->dispose_has_run = TRUE;
if (sheet->model) g_object_unref (sheet->model);
- if (sheet->row_geometry) g_object_unref (sheet->row_geometry);
- if (sheet->column_geometry) g_object_unref (sheet->column_geometry);
-
- g_object_unref (sheet->entry_container);
- sheet->entry_container = NULL;
+ if (sheet->vaxis) g_object_unref (sheet->vaxis);
+ if (sheet->haxis) g_object_unref (sheet->haxis);
g_object_unref (sheet->button);
sheet->button = NULL;
sheet->vadjustment = NULL;
}
- children = sheet->children;
- while (children)
- {
- GtkSheetChild *child = (GtkSheetChild *)children->data;
- if (child && child->widget)
- gtk_sheet_remove (GTK_CONTAINER (sheet), child->widget);
- children = sheet->children;
- }
- sheet->children = NULL;
-
if (G_OBJECT_CLASS (parent_class)->dispose)
(*G_OBJECT_CLASS (parent_class)->dispose) (object);
}
gtk_style_set_background (widget->style, widget->window, widget->state);
}
+ set_entry_widget_font (sheet);
}
+#define BORDER_WIDTH 3
+
static void
-gtk_sheet_realize (GtkWidget * widget)
+gtk_sheet_realize (GtkWidget *widget)
{
GtkSheet *sheet;
GdkWindowAttr attributes;
- gint attributes_mask;
- GdkGCValues values, auxvalues;
+ const gint attributes_mask =
+ GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR;
+
+ GdkGCValues values;
GdkColormap *colormap;
- GtkSheetChild *child;
- GList *children;
+ GdkDisplay *display;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_SHEET (widget));
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+ colormap = gtk_widget_get_colormap (widget);
+ display = gtk_widget_get_display (widget);
+
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.colormap = colormap;
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK);
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP |
- GDK_WA_CURSOR;
- attributes.cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
+ attributes.cursor = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW);
/* main window */
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+ gdk_color_parse ("white", &sheet->color[BG_COLOR]);
+ gdk_colormap_alloc_color (colormap, &sheet->color[BG_COLOR], FALSE,
+ TRUE);
+ gdk_color_parse ("gray", &sheet->color[GRID_COLOR]);
+ gdk_colormap_alloc_color (colormap, &sheet->color[GRID_COLOR], FALSE,
+ TRUE);
+
attributes.x = 0;
- if (sheet->row_titles_visible)
- attributes.x = sheet->row_title_area.width;
attributes.y = 0;
attributes.width = sheet->column_title_area.width;
attributes.height = sheet->column_title_area.height;
+
/* column - title window */
- sheet->column_title_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+ sheet->column_title_window =
+ gdk_window_new (widget->window, &attributes, attributes_mask);
gdk_window_set_user_data (sheet->column_title_window, sheet);
- gtk_style_set_background (widget->style, sheet->column_title_window, GTK_STATE_NORMAL);
+ gtk_style_set_background (widget->style, sheet->column_title_window,
+ GTK_STATE_NORMAL);
+
attributes.x = 0;
attributes.y = 0;
- if (sheet->column_titles_visible)
- attributes.y = sheet->column_title_area.height;
attributes.width = sheet->row_title_area.width;
attributes.height = sheet->row_title_area.height;
/* row - title window */
- sheet->row_title_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+ sheet->row_title_window = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
gdk_window_set_user_data (sheet->row_title_window, sheet);
- gtk_style_set_background (widget->style, sheet->row_title_window, GTK_STATE_NORMAL);
+ gtk_style_set_background (widget->style, sheet->row_title_window,
+ GTK_STATE_NORMAL);
/* sheet - window */
- attributes.cursor = gdk_cursor_new (GDK_PLUS);
+ attributes.cursor = gdk_cursor_new_for_display (display, GDK_PLUS);
attributes.x = 0;
attributes.y = 0;
- attributes.width = sheet->sheet_window_width,
- attributes.height = sheet->sheet_window_height;
- sheet->sheet_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+ sheet->sheet_window = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
gdk_window_set_user_data (sheet->sheet_window, sheet);
gdk_cursor_unref (attributes.cursor);
gdk_window_set_background (sheet->sheet_window, &widget->style->white);
gdk_window_show (sheet->sheet_window);
- /* backing_pixmap */
- gtk_sheet_make_backing_pixmap (sheet, 0, 0);
-
/* GCs */
- if (sheet->fg_gc)
- g_object_unref (sheet->fg_gc);
- if (sheet->bg_gc)
- g_object_unref (sheet->bg_gc);
sheet->fg_gc = gdk_gc_new (widget->window);
sheet->bg_gc = gdk_gc_new (widget->window);
- colormap = gtk_widget_get_colormap (widget);
-
- gdk_gc_get_values (sheet->fg_gc, &auxvalues);
-
values.foreground = widget->style->white;
values.function = GDK_INVERT;
values.subwindow_mode = GDK_INCLUDE_INFERIORS;
- if (sheet->xor_gc)
- g_object_unref (sheet->xor_gc);
+ values.line_width = BORDER_WIDTH;
+
sheet->xor_gc = gdk_gc_new_with_values (widget->window,
&values,
GDK_GC_FOREGROUND |
GDK_GC_FUNCTION |
- GDK_GC_SUBWINDOW);
+ GDK_GC_SUBWINDOW |
+ GDK_GC_LINE_WIDTH
+ );
gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window);
gtk_widget_set_parent (sheet->button, GTK_WIDGET (sheet));
- gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_PLUS);
+ sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_PLUS);
if (sheet->column_titles_visible)
gdk_window_show (sheet->column_title_window);
if (sheet->row_titles_visible)
gdk_window_show (sheet->row_title_window);
- size_allocate_row_title_buttons (sheet);
- size_allocate_column_title_buttons (sheet);
-
- children = sheet->children;
- while (children)
- {
- child = children->data;
- children = children->next;
+ sheet->hover_window = create_hover_window ();
- gtk_sheet_realize_child (sheet, child);
- }
+ draw_row_title_buttons (sheet);
+ draw_column_title_buttons (sheet);
gtk_sheet_update_primary_selection (sheet);
}
static void
global_button_clicked (GtkWidget *widget, gpointer data)
{
- gboolean veto;
-
- gtk_sheet_click_cell (GTK_SHEET (data), - 1, - 1, &veto);
- gtk_widget_grab_focus (GTK_WIDGET (data));
+ gtk_sheet_click_cell (GTK_SHEET (data), -1, -1);
}
static void
-gtk_sheet_unrealize (GtkWidget * widget)
+gtk_sheet_unrealize (GtkWidget *widget)
{
GtkSheet *sheet;
sheet = GTK_SHEET (widget);
gdk_cursor_unref (sheet->cursor_drag);
+ sheet->cursor_drag = NULL;
+
+ gdk_colormap_free_colors (gtk_widget_get_colormap (widget),
+ sheet->color, n_COLORS);
g_object_unref (sheet->xor_gc);
g_object_unref (sheet->fg_gc);
g_object_unref (sheet->bg_gc);
+ destroy_hover_window (sheet->hover_window);
+
gdk_window_destroy (sheet->sheet_window);
gdk_window_destroy (sheet->column_title_window);
gdk_window_destroy (sheet->row_title_window);
- if (sheet->pixmap)
- {
- g_object_unref (sheet->pixmap);
- sheet->pixmap = NULL;
- }
-
- sheet->column_title_window = NULL;
- sheet->sheet_window = NULL;
- sheet->xor_gc = NULL;
- sheet->fg_gc = NULL;
- sheet->bg_gc = NULL;
-
gtk_widget_unparent (sheet->entry_widget);
if (sheet->button != NULL)
gtk_widget_unparent (sheet->button);
}
static void
-gtk_sheet_map (GtkWidget * widget)
+gtk_sheet_map (GtkWidget *widget)
{
GtkSheet *sheet = GTK_SHEET (widget);
- GtkSheetChild *child;
- GList *children;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_SHEET (widget));
if (sheet->column_titles_visible)
{
- size_allocate_column_title_buttons (sheet);
+ draw_column_title_buttons (sheet);
gdk_window_show (sheet->column_title_window);
}
if (sheet->row_titles_visible)
{
- size_allocate_row_title_buttons (sheet);
+ draw_row_title_buttons (sheet);
gdk_window_show (sheet->row_title_window);
}
gtk_widget_map (GTK_BIN (sheet->button)->child);
gtk_sheet_range_draw (sheet, NULL);
- gtk_sheet_activate_cell (sheet,
- sheet->active_cell.row,
- sheet->active_cell.col);
-
- children = sheet->children;
- while (children)
- {
- child = children->data;
- children = children->next;
-
- if (GTK_WIDGET_VISIBLE (child->widget) &&
- !GTK_WIDGET_MAPPED (child->widget))
- {
- gtk_widget_map (child->widget);
- gtk_sheet_position_child (sheet, child);
- }
- }
-
+ change_active_cell (sheet,
+ sheet->active_cell.row,
+ sheet->active_cell.col);
}
}
static void
-gtk_sheet_unmap (GtkWidget * widget)
+gtk_sheet_unmap (GtkWidget *widget)
{
- GtkSheet *sheet;
- GtkSheetChild *child;
- GList *children;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_SHEET (widget));
-
- sheet = GTK_SHEET (widget);
-
- if (GTK_WIDGET_MAPPED (widget))
- {
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
-
- gdk_window_hide (sheet->sheet_window);
- if (sheet->column_titles_visible)
- gdk_window_hide (sheet->column_title_window);
- if (sheet->row_titles_visible)
- gdk_window_hide (sheet->row_title_window);
- gdk_window_hide (widget->window);
+ GtkSheet *sheet = GTK_SHEET (widget);
- if (GTK_WIDGET_MAPPED (sheet->entry_widget))
- gtk_widget_unmap (sheet->entry_widget);
+ if (!GTK_WIDGET_MAPPED (widget))
+ return;
- if (GTK_WIDGET_MAPPED (sheet->button))
- gtk_widget_unmap (sheet->button);
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
- children = sheet->children;
- while (children)
- {
- child = children->data;
- children = children->next;
+ gdk_window_hide (sheet->sheet_window);
+ if (sheet->column_titles_visible)
+ gdk_window_hide (sheet->column_title_window);
+ if (sheet->row_titles_visible)
+ gdk_window_hide (sheet->row_title_window);
+ gdk_window_hide (widget->window);
- if (GTK_WIDGET_VISIBLE (child->widget) &&
- GTK_WIDGET_MAPPED (child->widget))
- {
- gtk_widget_unmap (child->widget);
- }
- }
+ if (GTK_WIDGET_MAPPED (sheet->entry_widget))
+ gtk_widget_unmap (sheet->entry_widget);
- }
+ if (GTK_WIDGET_MAPPED (sheet->button))
+ gtk_widget_unmap (sheet->button);
}
static void
-gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col)
+gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint col)
{
- GtkWidget *widget;
- GdkGC *fg_gc, *bg_gc;
+ PangoLayout *layout;
+ PangoRectangle text;
+ PangoFontDescription *font_desc = GTK_WIDGET (sheet)->style->font_desc;
+ gint font_height;
+
+ gchar *label;
+
GtkSheetCellAttr attributes;
GdkRectangle area;
g_return_if_fail (sheet != NULL);
- /* bail now if we arn't drawable yet */
+ /* bail now if we aren't yet drawable */
if (!GTK_WIDGET_DRAWABLE (sheet)) return;
- if (row < 0 || row >= yyy_row_count (sheet)) return;
- if (col < 0 || col >= xxx_column_count (sheet)) return;
- if (! xxx_column_is_visible (sheet, col)) return;
- if (! yyy_row_is_visible (sheet, row)) return;
+ if (row < 0 ||
+ row >= psppire_axis_unit_count (sheet->vaxis))
+ return;
- widget = GTK_WIDGET (sheet);
+ if (col < 0 ||
+ col >= psppire_axis_unit_count (sheet->haxis))
+ return;
gtk_sheet_get_attributes (sheet, row, col, &attributes);
gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground);
gdk_gc_set_foreground (sheet->bg_gc, &attributes.background);
- fg_gc = sheet->fg_gc;
- bg_gc = sheet->bg_gc;
-
- area.x = COLUMN_LEFT_XPIXEL (sheet, col);
- area.y = ROW_TOP_YPIXEL (sheet, row);
- area.width= xxx_column_width (sheet, col);
- area.height = yyy_row_height (sheet, row);
-
- gdk_draw_rectangle (sheet->pixmap,
- bg_gc,
- TRUE,
- area.x,
- area.y,
- area.width,
- area.height);
+ rectangle_from_cell (sheet, row, col, &area);
gdk_gc_set_line_attributes (sheet->fg_gc, 1, 0, 0, 0);
if (sheet->show_grid)
{
- gdk_gc_set_foreground (sheet->bg_gc, &sheet->grid_color);
+ gdk_gc_set_foreground (sheet->bg_gc, &sheet->color[GRID_COLOR]);
- gdk_draw_rectangle (sheet->pixmap,
+ gdk_draw_rectangle (sheet->sheet_window,
sheet->bg_gc,
FALSE,
area.x, area.y,
area.width, area.height);
}
-}
-
-static void
-gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
-{
- GtkWidget *widget;
- GdkRectangle area;
- gint i;
- gint text_width, text_height, y;
- gint xoffset = 0;
- gint size, sizel, sizer;
- GdkGC *fg_gc, *bg_gc;
- GtkSheetCellAttr attributes;
- PangoLayout *layout;
- PangoRectangle rect;
- PangoRectangle logical_rect;
- PangoLayoutLine *line;
- PangoFontMetrics *metrics;
- PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET (sheet));
- gint ascent, descent, y_pos;
-
- gchar *label;
-
- g_return_if_fail (sheet != NULL);
- /* bail now if we aren't drawable yet */
- if (!GTK_WIDGET_DRAWABLE (sheet))
- return;
label = gtk_sheet_cell_get_text (sheet, row, col);
- if (!label)
+ if (NULL == label)
return;
- if (row < 0 || row >= yyy_row_count (sheet)) return;
- if (col < 0 || col >= xxx_column_count (sheet)) return;
- if (! xxx_column_is_visible (sheet, col)) return;
- if (!yyy_row_is_visible (sheet, row)) return;
-
-
- widget = GTK_WIDGET (sheet);
-
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
-
- /* select GC for background rectangle */
- gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground);
- gdk_gc_set_foreground (sheet->bg_gc, &attributes.background);
-
- fg_gc = sheet->fg_gc;
- bg_gc = sheet->bg_gc;
-
- area.x = COLUMN_LEFT_XPIXEL (sheet, col);
- area.y = ROW_TOP_YPIXEL (sheet, row);
- area.width = xxx_column_width (sheet, col);
- area.height = yyy_row_height (sheet, row);
-
layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), label);
dispose_string (sheet, label);
- pango_layout_set_font_description (layout, attributes.font_desc);
- pango_layout_get_pixel_extents (layout, NULL, &rect);
- line = pango_layout_get_lines (layout)->data;
- pango_layout_line_get_extents (line, NULL, &logical_rect);
+ pango_layout_set_font_description (layout, font_desc);
- metrics = pango_context_get_metrics (context,
- attributes.font_desc,
- pango_context_get_language (context));
+ pango_layout_get_pixel_extents (layout, NULL, &text);
- ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
- descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
+ gdk_gc_set_clip_rectangle (sheet->fg_gc, &area);
- pango_font_metrics_unref (metrics);
+ font_height = pango_font_description_get_size (font_desc);
+ if ( !pango_font_description_get_size_is_absolute (font_desc))
+ font_height /= PANGO_SCALE;
- /* Align primarily for locale's ascent / descent */
-
- logical_rect.height /= PANGO_SCALE;
- logical_rect.y /= PANGO_SCALE;
- y_pos = area.height - logical_rect.height;
-
- if (logical_rect.height > area.height)
- y_pos = (logical_rect.height - area.height - 2 * CELLOFFSET) / 2;
- else if (y_pos < 0)
- y_pos = 0;
- else if (y_pos + logical_rect.height > area.height)
- y_pos = area.height - logical_rect.height;
-
- text_width = rect.width;
- text_height = rect.height;
- y = area.y + y_pos - CELLOFFSET;
+ /* Centre the text vertically */
+ area.y += (area.height - font_height) / 2.0;
switch (attributes.justification)
{
case GTK_JUSTIFY_RIGHT:
- size = area.width;
- area.x +=area.width;
- {
- for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--)
- {
- if ( !gtk_sheet_cell_empty (sheet, row, i)) break;
- if (size >= text_width + CELLOFFSET) break;
- size +=xxx_column_width (sheet, i);
- xxx_column_set_right_column (sheet, i,
- MAX (col,
- xxx_column_right_column (sheet, i)));
- }
- area.width = size;
- }
- area.x -= size;
- xoffset += area.width - text_width - 2 * CELLOFFSET -
- attributes.border.width / 2;
+ area.x += area.width - text.width;
break;
case GTK_JUSTIFY_CENTER:
- sizel = area.width / 2;
- sizer = area.width / 2;
- area.x += area.width / 2;
- {
- for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++)
- {
- if ( ! gtk_sheet_cell_empty (sheet, row, i)) break;
- if (sizer >= text_width / 2) break;
- sizer += xxx_column_width (sheet, i);
- xxx_column_set_left_column (sheet, i,
- MIN (
- col,
- xxx_column_left_column (sheet, i)));
- }
- for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--)
- {
- if ( ! gtk_sheet_cell_empty (sheet, row, i)) break;
- if (sizel >= text_width / 2) break;
- sizel +=xxx_column_width (sheet, i);
- xxx_column_set_right_column (sheet, i,
- MAX (col,
- xxx_column_right_column (sheet, i)));
- }
- size = MIN (sizel, sizer);
- }
- area.x -= sizel;
- xoffset += sizel - text_width / 2 - CELLOFFSET;
- area.width = sizel + sizer;
+ area.x += (area.width - text.width) / 2.0;
break;
case GTK_JUSTIFY_LEFT:
+ /* Do nothing */
+ break;
default:
- size = area.width;
- {
- for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++)
- {
- if (! gtk_sheet_cell_empty (sheet, row, i)) break;
- if (size >= text_width + CELLOFFSET) break;
- size +=xxx_column_width (sheet, i);
- xxx_column_set_left_column (sheet, i,
- MIN (
- col,
- xxx_column_left_column (sheet, i)));
-
- }
- area.width = size;
- }
- xoffset += attributes.border.width / 2;
+ g_critical ("Unhandled justification %d in column %d\n",
+ attributes.justification, col);
break;
}
- gdk_gc_set_clip_rectangle (fg_gc, &area);
-
-
- gdk_draw_layout (sheet->pixmap, fg_gc,
- area.x + xoffset + CELLOFFSET,
- y,
+ gdk_draw_layout (sheet->sheet_window, sheet->fg_gc,
+ area.x,
+ area.y,
layout);
- gdk_gc_set_clip_rectangle (fg_gc, NULL);
+ gdk_gc_set_clip_rectangle (sheet->fg_gc, NULL);
g_object_unref (layout);
+}
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- area.x,
- area.y,
- area.x,
- area.y,
- area.width,
- area.height);
-}
static void
gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range)
{
gint i, j;
- GtkSheetRange drawing_range;
+
GdkRectangle area;
+ GtkSheetRange drawing_range;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_SHEET (sheet));
if (range == NULL)
{
- drawing_range.row0 = MIN_VISIBLE_ROW (sheet);
- drawing_range.col0 = MIN_VISIBLE_COLUMN (sheet);
- drawing_range.rowi = MIN (MAX_VISIBLE_ROW (sheet),
- yyy_row_count (sheet) - 1);
- drawing_range.coli = MAX_VISIBLE_COLUMN (sheet);
-
-
- gdk_draw_rectangle (sheet->pixmap,
- GTK_WIDGET (sheet)->style->white_gc,
- TRUE,
- 0, 0,
- sheet->sheet_window_width,
- sheet->sheet_window_height);
+ drawing_range.row0 = min_visible_row (sheet);
+ drawing_range.col0 = min_visible_column (sheet);
+ drawing_range.rowi = MIN (max_visible_row (sheet),
+ psppire_axis_unit_count (sheet->vaxis) - 1);
+ drawing_range.coli = max_visible_column (sheet);
+ gdk_drawable_get_size (sheet->sheet_window, &area.width, &area.height);
+ area.x = area.y = 0;
}
else
{
- drawing_range.row0 = MAX (range->row0, MIN_VISIBLE_ROW (sheet));
- drawing_range.col0 = MAX (range->col0, MIN_VISIBLE_COLUMN (sheet));
- drawing_range.rowi = MIN (range->rowi, MAX_VISIBLE_ROW (sheet));
- drawing_range.coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet));
- }
-
- if (drawing_range.coli == xxx_column_count (sheet) - 1)
- {
- area.x = COLUMN_LEFT_XPIXEL (sheet,
- xxx_column_count (sheet) - 1) +
- xxx_column_width (sheet, xxx_column_count (sheet) - 1) + 1;
-
- area.y = 0;
+ drawing_range.row0 = MAX (range->row0, min_visible_row (sheet));
+ drawing_range.col0 = MAX (range->col0, min_visible_column (sheet));
+ drawing_range.rowi = MIN (range->rowi, max_visible_row (sheet));
+ drawing_range.coli = MIN (range->coli, max_visible_column (sheet));
- gdk_gc_set_foreground (sheet->fg_gc, &sheet->bg_color);
-
- gdk_draw_rectangle (sheet->pixmap,
- sheet->fg_gc,
- TRUE,
- area.x, area.y,
- sheet->sheet_window_width - area.x,
- sheet->sheet_window_height);
-
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- area.x,
- area.y,
- area.x,
- area.y,
- sheet->sheet_window_width - area.x,
- sheet->sheet_window_height);
+ rectangle_from_range (sheet, &drawing_range, &area);
}
- if (drawing_range.rowi == yyy_row_count (sheet) - 1)
- {
- area.x = 0;
- area.y = ROW_TOP_YPIXEL (sheet,
- yyy_row_count (sheet) - 1) +
- yyy_row_height (sheet, yyy_row_count (sheet) - 1) + 1;
-
- gdk_gc_set_foreground (sheet->fg_gc, &sheet->bg_color);
+ g_return_if_fail (drawing_range.rowi >= drawing_range.row0);
+ g_return_if_fail (drawing_range.coli >= drawing_range.col0);
- gdk_draw_rectangle (sheet->pixmap,
- sheet->fg_gc,
- TRUE,
- area.x, area.y,
- sheet->sheet_window_width,
- sheet->sheet_window_height - area.y);
-
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- area.x,
- area.y,
- area.x,
- area.y,
- sheet->sheet_window_width,
- sheet->sheet_window_height - area.y);
- }
+ gdk_window_begin_paint_rect (sheet->sheet_window, &area);
for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
for (j = drawing_range.col0; j <= drawing_range.coli; j++)
{
- gtk_sheet_cell_draw_default (sheet, i, j);
- gtk_sheet_cell_draw_label (sheet, i, j);
+ gtk_sheet_cell_draw (sheet, i, j);
}
- gtk_sheet_draw_backing_pixmap (sheet, drawing_range);
-
if (sheet->state != GTK_SHEET_NORMAL &&
- gtk_sheet_range_isvisible (sheet, sheet->range))
+ gtk_sheet_range_isvisible (sheet, &sheet->range))
gtk_sheet_range_draw_selection (sheet, drawing_range);
if (sheet->state == GTK_STATE_NORMAL &&
sheet->active_cell.row <= drawing_range.rowi &&
sheet->active_cell.col >= drawing_range.col0 &&
sheet->active_cell.col <= drawing_range.coli)
- gtk_sheet_show_active_cell (sheet);
+ gtk_sheet_show_entry_widget (sheet);
+
+ gdk_window_end_paint (sheet->sheet_window);
}
static void
range.row0 > sheet->range.rowi || range.rowi < sheet->range.row0)
return;
- if (!gtk_sheet_range_isvisible (sheet, range)) return;
+ if (!gtk_sheet_range_isvisible (sheet, &range)) return;
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
aux = range;
range.row0 = MAX (sheet->range.row0, range.row0);
range.rowi = MIN (sheet->range.rowi, range.rowi);
- range.col0 = MAX (range.col0, MIN_VISIBLE_COLUMN (sheet));
- range.coli = MIN (range.coli, MAX_VISIBLE_COLUMN (sheet));
- range.row0 = MAX (range.row0, MIN_VISIBLE_ROW (sheet));
- range.rowi = MIN (range.rowi, MAX_VISIBLE_ROW (sheet));
+ range.col0 = MAX (range.col0, min_visible_column (sheet));
+ range.coli = MIN (range.coli, max_visible_column (sheet));
+ range.row0 = MAX (range.row0, min_visible_row (sheet));
+ range.rowi = MIN (range.rowi, max_visible_row (sheet));
for (i = range.row0; i <= range.rowi; i++)
{
for (j = range.col0; j <= range.coli; j++)
{
-
- if (gtk_sheet_cell_get_state (sheet, i, j) == GTK_STATE_SELECTED &&
- xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i))
+ if (gtk_sheet_cell_get_state (sheet, i, j) == GTK_STATE_SELECTED)
{
-
- area.x = COLUMN_LEFT_XPIXEL (sheet, j);
- area.y = ROW_TOP_YPIXEL (sheet, i);
- area.width= xxx_column_width (sheet, j);
- area.height = yyy_row_height (sheet, i);
+ rectangle_from_cell (sheet, i, j, &area);
if (i == sheet->range.row0)
{
gtk_sheet_draw_border (sheet, sheet->range);
}
-static void
-gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, GtkSheetRange range)
-{
- gint x, y, width, height;
-
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
-
- x = COLUMN_LEFT_XPIXEL (sheet, range.col0);
- y = ROW_TOP_YPIXEL (sheet, range.row0);
- width = COLUMN_LEFT_XPIXEL (sheet, range.coli) - x +
- xxx_column_width (sheet, range.coli);
-
- height = ROW_TOP_YPIXEL (sheet, range.rowi)- y + yyy_row_height (sheet, range.rowi);
-
- if (range.row0 == sheet->range.row0)
- {
- y = y - 5;
- height = height + 5;
- }
- if (range.rowi == sheet->range.rowi) height = height + 5;
- if (range.col0 == sheet->range.col0)
- {
- x = x - 5;
- width = width + 5;
- }
- if (range.coli == sheet->range.coli) width = width + 5;
-
- width = MIN (width, sheet->sheet_window_width - x);
- height = MIN (height, sheet->sheet_window_height - y);
-
- x--;
- y--;
- width +=2;
- height +=2;
-
- x = (sheet->row_titles_visible)
- ? MAX (x, sheet->row_title_area.width) : MAX (x, 0);
- y = (sheet->column_titles_visible)
- ? MAX (y, sheet->column_title_area.height) : MAX (y, 0);
-
- if (range.coli == xxx_column_count (sheet) - 1)
- width = sheet->sheet_window_width - x;
- if (range.rowi == yyy_row_count (sheet) - 1)
- height = sheet->sheet_window_height - y;
-
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x,
- y,
- x,
- y,
- width + 1,
- height + 1);
-}
-
-
-void
-gtk_sheet_set_cell_text (GtkSheet *sheet, gint row, gint col, const gchar *text)
-{
- GtkSheetCellAttr attributes;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
- if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return;
- if (col < 0 || row < 0) return;
-
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
- gtk_sheet_set_cell (sheet, row, col, attributes.justification, text);
-}
-
-static inline gint
-safe_strcmp (const gchar *s1, const gchar *s2)
+static inline gint
+safe_strcmp (const gchar *s1, const gchar *s2)
{
if ( !s1 && !s2) return 0;
- if ( !s1) return - 1;
+ if ( !s1) return -1;
if ( !s2) return +1;
return strcmp (s1, s2);
}
-void
+static void
gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col,
GtkJustification justification,
const gchar *text)
{
GSheetModel *model ;
- gboolean changed ;
gchar *old_text ;
- GtkSheetRange range;
- gint text_width;
- GtkSheetCellAttr attributes;
-
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet));
- if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return;
- if (col < 0 || row < 0) return;
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
+ if (col >= psppire_axis_unit_count (sheet->haxis)
+ || row >= psppire_axis_unit_count (sheet->vaxis))
+ return;
- attributes.justification = justification;
+ if (col < 0 || row < 0) return;
model = gtk_sheet_get_model (sheet);
old_text = g_sheet_model_get_string (model, row, col);
- changed = FALSE;
-
if (0 != safe_strcmp (old_text, text))
- changed = g_sheet_model_set_string (model, text, row, col);
+ g_sheet_model_set_string (model, text, row, col);
if ( g_sheet_model_free_strings (model))
g_free (old_text);
-
-
- if (changed && attributes.is_visible)
- {
- gchar *s = gtk_sheet_cell_get_text (sheet, row, col);
- text_width = 0;
- if (s && strlen (s) > 0)
- {
- text_width = STRING_WIDTH (GTK_WIDGET (sheet),
- attributes.font_desc, text);
- }
- dispose_string (sheet, s);
-
- range.row0 = row;
- range.rowi = row;
- range.col0 = MIN_VISIBLE_COLUMN (sheet);
- range.coli = MAX_VISIBLE_COLUMN (sheet);
-
- if (gtk_sheet_autoresize (sheet) &&
- text_width > xxx_column_width (sheet, col) -
- 2 * CELLOFFSET- attributes.border.width)
- {
- gtk_sheet_set_column_width (sheet, col, text_width + 2 * CELLOFFSET
- + attributes.border.width);
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING);
- }
- else
- if (!GTK_SHEET_IS_FROZEN (sheet))
- gtk_sheet_range_draw (sheet, &range);
- }
-
- if ( changed )
- g_signal_emit (sheet, sheet_signals[CHANGED], 0, row, col);
-
}
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet));
- if (column >= xxx_column_count (sheet) ||
- row >= yyy_row_count (sheet)) return;
+ if (column >= psppire_axis_unit_count (sheet->haxis) ||
+ row >= psppire_axis_unit_count (sheet->vaxis)) return;
if (column < 0 || row < 0) return;
range.row0 = row;
range.rowi = row;
- range.col0 = MIN_VISIBLE_COLUMN (sheet);
- range.coli = MAX_VISIBLE_COLUMN (sheet);
+ range.col0 = min_visible_column (sheet);
+ range.coli = max_visible_column (sheet);
gtk_sheet_real_cell_clear (sheet, row, column);
- if (!GTK_SHEET_IS_FROZEN (sheet))
- {
- gtk_sheet_range_draw (sheet, &range);
- }
+ gtk_sheet_range_draw (sheet, &range);
}
static void
dispose_string (sheet, old_text);
}
-void
-gtk_sheet_range_clear (GtkSheet *sheet, const GtkSheetRange *range)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- gtk_sheet_real_range_clear (sheet, range);
-}
-
-static void
-gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range)
-{
- gint i, j;
- GtkSheetRange clear;
-
- if (!range)
- {
- clear.row0 = 0;
- clear.rowi = yyy_row_count (sheet) - 1;
- clear.col0 = 0;
- clear.coli = xxx_column_count (sheet) - 1;
- }
- else
- clear=*range;
-
- clear.row0 = MAX (clear.row0, 0);
- clear.col0 = MAX (clear.col0, 0);
- clear.rowi = MIN (clear.rowi, yyy_row_count (sheet) - 1 );
- clear.coli = MIN (clear.coli, xxx_column_count (sheet) - 1 );
-
- for (i = clear.row0; i <= clear.rowi; i++)
- for (j = clear.col0; j <= clear.coli; j++)
- {
- gtk_sheet_real_cell_clear (sheet, i, j);
- }
-
- gtk_sheet_range_draw (sheet, NULL);
-}
-
-
-static gboolean
-gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col)
-{
- gboolean empty;
- char *text = gtk_sheet_cell_get_text (sheet, row, col);
- empty = (text == NULL );
-
- dispose_string (sheet, text);
-
- return empty;
-}
-
-
gchar *
gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col)
{
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
- if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet))
+ if (col >= psppire_axis_unit_count (sheet->haxis) || row >= psppire_axis_unit_count (sheet->vaxis))
return NULL;
if (col < 0 || row < 0) return NULL;
}
-GtkStateType
+static GtkStateType
gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col)
{
gint state;
g_return_val_if_fail (sheet != NULL, 0);
g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
- if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return 0;
+ if (col >= psppire_axis_unit_count (sheet->haxis) || row >= psppire_axis_unit_count (sheet->vaxis)) return 0;
if (col < 0 || row < 0) return 0;
state = sheet->state;
return GTK_STATE_NORMAL;
}
-/* Convert X, Y (in pixels) to *ROW, *COLUMN (in cell coords)
- -1 indicates the title buttons.
+/* Convert X, Y (in pixels) to *ROW, *COLUMN
If the function returns FALSE, then the results will be unreliable.
*/
-gboolean
+static gboolean
gtk_sheet_get_pixel_info (GtkSheet *sheet,
gint x,
gint y,
if (x < 0)
return FALSE;
- if ( y < sheet->column_title_area.height + sheet->column_title_area.y)
- *row = -1;
+ if ( sheet->column_titles_visible)
+ y -= sheet->column_title_area.height;
+ y += sheet->vadjustment->value;
+
+ if ( y < 0 && sheet->column_titles_visible)
+ {
+ trow = -1;
+ }
else
{
- trow = ROW_FROM_YPIXEL (sheet, y);
- if (trow > yyy_row_count (sheet))
+ trow = row_from_ypixel (sheet, y);
+ if (trow > psppire_axis_unit_count (sheet->vaxis))
return FALSE;
-
- *row = trow;
}
- if ( x < sheet->row_title_area.width + sheet->row_title_area.x)
- *column = -1;
+ *row = trow;
+
+ if ( sheet->row_titles_visible)
+ x -= sheet->row_title_area.width;
+
+ x += sheet->hadjustment->value;
+
+ if ( x < 0 && sheet->row_titles_visible)
+ {
+ tcol = -1;
+ }
else
{
- tcol = COLUMN_FROM_XPIXEL (sheet, x);
- if (tcol > xxx_column_count (sheet))
+ tcol = column_from_xpixel (sheet, x);
+ if (tcol > psppire_axis_unit_count (sheet->haxis))
return FALSE;
-
- *column = tcol;
}
+ *column = tcol;
+
return TRUE;
}
gboolean
-gtk_sheet_get_cell_area (GtkSheet * sheet,
+gtk_sheet_get_cell_area (GtkSheet *sheet,
gint row,
gint column,
GdkRectangle *area)
g_return_val_if_fail (sheet != NULL, 0);
g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
- if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet))
+ if (row >= psppire_axis_unit_count (sheet->vaxis) || column >= psppire_axis_unit_count (sheet->haxis))
return FALSE;
- area->x = (column == -1) ? 0 : (COLUMN_LEFT_XPIXEL (sheet, column) -
- (sheet->row_titles_visible
- ? sheet->row_title_area.width
- : 0));
- area->y = (row == -1) ? 0 : (ROW_TOP_YPIXEL (sheet, row) -
- (sheet->column_titles_visible
- ? sheet->column_title_area.height
- : 0));
+ area->x = (column == -1) ? 0 : psppire_axis_start_pixel (sheet->haxis, column);
+ area->y = (row == -1) ? 0 : psppire_axis_start_pixel (sheet->vaxis, row);
+
area->width= (column == -1) ? sheet->row_title_area.width
- : xxx_column_width (sheet, column);
+ : psppire_axis_unit_size (sheet->haxis, column);
area->height= (row == -1) ? sheet->column_title_area.height
- : yyy_row_height (sheet, row);
+ : psppire_axis_unit_size (sheet->vaxis, row);
return TRUE;
}
-gboolean
-gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column)
+void
+gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint col)
{
- g_return_val_if_fail (sheet != NULL, 0);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
+ g_return_if_fail (sheet != NULL);
+ g_return_if_fail (GTK_IS_SHEET (sheet));
- if (row < - 1 || column < - 1) return FALSE;
- if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet))
- return FALSE;
+ if (row < -1 || col < -1)
+ return;
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
- gtk_sheet_deactivate_cell (sheet);
+ if (row >= psppire_axis_unit_count (sheet->vaxis)
+ ||
+ col >= psppire_axis_unit_count (sheet->haxis))
+ return;
sheet->active_cell.row = row;
- sheet->active_cell.col = column;
+ sheet->active_cell.col = col;
+
+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ return;
- if ( row == -1 || column == -1)
+ if ( row == -1 || col == -1)
{
- gtk_sheet_hide_active_cell (sheet);
- return TRUE;
+ gtk_sheet_hide_entry_widget (sheet);
+ return;
}
- if (!gtk_sheet_activate_cell (sheet, row, column)) return FALSE;
-
- if (gtk_sheet_autoscroll (sheet))
- gtk_sheet_move_query (sheet, row, column);
-
- return TRUE;
+ change_active_cell (sheet, row, col);
}
void
sheet->active_cell.row = -1;
sheet->active_cell.col = -1;
- text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)));
-
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IS_FROZEN);
+ text = gtk_entry_get_text (gtk_sheet_get_entry (sheet));
if (text && strlen (text) > 0)
{
gtk_sheet_set_cell (sheet, row, col, justification, text);
}
- if (sheet->freeze_count == 0)
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN);
-
sheet->active_cell.row = row;;
sheet->active_cell.col = col;
}
static void
-gtk_sheet_deactivate_cell (GtkSheet *sheet)
-{
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return ;
- if (sheet->state != GTK_SHEET_NORMAL) return ;
-
- if ( sheet->active_cell.row == -1 || sheet->active_cell.col == -1 )
- return ;
-
- g_signal_emit (sheet, sheet_signals[DEACTIVATE], 0,
- sheet->active_cell.row,
- sheet->active_cell.col);
-
-
- g_signal_handlers_disconnect_by_func (gtk_sheet_get_entry (sheet),
- G_CALLBACK (gtk_sheet_entry_changed),
- sheet);
-
- gtk_sheet_hide_active_cell (sheet);
- sheet->active_cell.row = -1;
- sheet->active_cell.col = -1;
-
- if (GTK_SHEET_REDRAW_PENDING (sheet))
- {
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING);
- gtk_sheet_range_draw (sheet, NULL);
- }
-}
-
-static void
-gtk_sheet_hide_active_cell (GtkSheet *sheet)
+gtk_sheet_hide_entry_widget (GtkSheet *sheet)
{
- const char *text;
- gint row, col;
- GtkJustification justification;
- GtkSheetCellAttr attributes;
-
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
-
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
-
- if (row < 0 || col < 0) return;
-
- if (sheet->freeze_count == 0)
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN);
-
- text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)));
-
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
- justification = attributes.justification;
+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ return;
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
+ if (sheet->active_cell.row < 0 ||
+ sheet->active_cell.col < 0) return;
gtk_widget_hide (sheet->entry_widget);
gtk_widget_unmap (sheet->entry_widget);
- if (row != -1 && col != -1)
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- COLUMN_LEFT_XPIXEL (sheet, col)- 1,
- ROW_TOP_YPIXEL (sheet, row)- 1,
- COLUMN_LEFT_XPIXEL (sheet, col)- 1,
- ROW_TOP_YPIXEL (sheet, row)- 1,
- xxx_column_width (sheet, col) + 4,
- yyy_row_height (sheet, row)+4);
-
- gtk_widget_grab_focus (GTK_WIDGET (sheet));
-
GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE);
-
}
-static gboolean
-gtk_sheet_activate_cell (GtkSheet *sheet, gint row, gint col)
+static void
+change_active_cell (GtkSheet *sheet, gint row, gint col)
{
- gboolean veto = TRUE;
+ gint old_row, old_col;
+ glong old_handler_id = sheet->entry_handler_id;
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
+ g_return_if_fail (GTK_IS_SHEET (sheet));
- if (row < 0 || col < 0) return FALSE;
+ if (row < 0 || col < 0)
+ return;
- if ( row > yyy_row_count (sheet) || col > xxx_column_count (sheet))
- return FALSE;
+ if ( row > psppire_axis_unit_count (sheet->vaxis)
+ || col > psppire_axis_unit_count (sheet->haxis))
+ return;
- if (!veto) return FALSE;
if (sheet->state != GTK_SHEET_NORMAL)
{
sheet->state = GTK_SHEET_NORMAL;
gtk_sheet_real_unselect_range (sheet, NULL);
}
+
+ g_signal_handler_block (sheet->entry_widget, sheet->entry_handler_id);
+
+ old_row = sheet->active_cell.row;
+ old_col = sheet->active_cell.col;
+
+ {
+ /* Redraw the neighbourhood of the old active cell */
+ GtkSheetRange r;
+ r.col0 = old_col - 1;
+ r.coli = old_col + 1;
+ r.row0 = old_row - 1;
+ r.rowi = old_row + 1;
+
+ maximize_int (&r.row0, 0);
+ maximize_int (&r.col0, 0);
+ minimize_int (&r.rowi, psppire_axis_unit_count (sheet->vaxis) - 1);
+ minimize_int (&r.coli, psppire_axis_unit_count (sheet->haxis) - 1);
+
+
+ if ( gtk_sheet_range_isvisible (sheet, &r))
+ gtk_sheet_range_draw (sheet, &r);
+ }
+
sheet->range.row0 = row;
sheet->range.col0 = col;
sheet->range.rowi = row;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- gtk_sheet_show_active_cell (sheet);
+ gtk_sheet_draw_active_cell (sheet);
+ gtk_sheet_show_entry_widget (sheet);
- g_signal_connect (gtk_sheet_get_entry (sheet),
- "changed",
- G_CALLBACK (gtk_sheet_entry_changed),
- sheet);
- _gtkextra_signal_emit (GTK_OBJECT (sheet), sheet_signals [ACTIVATE], row, col, &veto);
+ g_signal_emit (sheet, sheet_signals [ACTIVATE], 0,
+ row, col, old_row, old_col);
- return TRUE;
+ if ( old_handler_id == sheet->entry_handler_id)
+ g_signal_handler_unblock (sheet->entry_widget, sheet->entry_handler_id);
}
static void
-gtk_sheet_show_active_cell (GtkSheet *sheet)
+gtk_sheet_show_entry_widget (GtkSheet *sheet)
{
GtkEntry *sheet_entry;
GtkSheetCellAttr attributes;
gchar *text = NULL;
- const gchar *old_text;
- GtkJustification justification;
gint row, col;
g_return_if_fail (sheet != NULL);
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE);
- sheet_entry = GTK_ENTRY (gtk_sheet_get_entry (sheet));
+ sheet_entry = gtk_sheet_get_entry (sheet);
gtk_sheet_get_attributes (sheet, row, col, &attributes);
- justification = GTK_JUSTIFY_LEFT;
-
- if (gtk_sheet_justify_entry (sheet))
- justification = attributes.justification;
text = gtk_sheet_cell_get_text (sheet, row, col);
if ( ! text )
text = g_strdup ("");
- gtk_entry_set_visibility (GTK_ENTRY (sheet_entry), attributes.is_visible);
-
-
- /*** Added by John Gotts. Mar 25, 2005 *********/
- old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry));
- if (strcmp (old_text, text) != 0)
+ if ( GTK_IS_ENTRY (sheet_entry))
{
- if (!GTK_IS_ITEM_ENTRY (sheet_entry))
- gtk_entry_set_text (GTK_ENTRY (sheet_entry), text);
- else
- gtk_item_entry_set_text (GTK_ITEM_ENTRY (sheet_entry), text, justification);
+ const gchar *old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry));
+ if (strcmp (old_text, text) != 0)
+ gtk_entry_set_text (sheet_entry, text);
+
+ switch (attributes.justification)
+ {
+ case GTK_JUSTIFY_RIGHT:
+ gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 1.0);
+ break;
+ case GTK_JUSTIFY_CENTER:
+ gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.5);
+ break;
+ case GTK_JUSTIFY_LEFT:
+ default:
+ gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.0);
+ break;
+ }
}
- gtk_sheet_entry_set_max_size (sheet);
gtk_sheet_size_allocate_entry (sheet);
+ gtk_widget_set_sensitive (GTK_WIDGET (sheet_entry),
+ g_sheet_model_is_editable (sheet->model,
+ row, col));
gtk_widget_map (sheet->entry_widget);
- gtk_widget_grab_focus (GTK_WIDGET (sheet_entry));
-
dispose_string (sheet, text);
}
-static void
+static gboolean
gtk_sheet_draw_active_cell (GtkSheet *sheet)
{
gint row, col;
GtkSheetRange range;
- if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (sheet))) return;
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
-
row = sheet->active_cell.row;
col = sheet->active_cell.col;
- if (row < 0 || col < 0) return;
+ if (row < 0 || col < 0) return FALSE;
- if (!gtk_sheet_cell_isvisible (sheet, row, col)) return;
+ if (!gtk_sheet_cell_isvisible (sheet, row, col))
+ return FALSE;
range.col0 = range.coli = col;
range.row0 = range.rowi = row;
gtk_sheet_draw_border (sheet, range);
-}
-
-
-static void
-gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height)
-{
- gint pixmap_width, pixmap_height;
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
+ return FALSE;
+}
- if (width == 0 && height == 0)
- {
- width = sheet->sheet_window_width + 80;
- height = sheet->sheet_window_height + 80;
- }
- if (!sheet->pixmap)
- {
- /* allocate */
- sheet->pixmap = gdk_pixmap_new (sheet->sheet_window,
- width, height,
- - 1);
- if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL);
- }
- else
- {
- /* reallocate if sizes don't match */
- gdk_drawable_get_size (sheet->pixmap,
- &pixmap_width, &pixmap_height);
- if ( (pixmap_width != width) || (pixmap_height != height))
- {
- g_object_unref (sheet->pixmap);
- sheet->pixmap = gdk_pixmap_new (sheet->sheet_window,
- width, height,
- - 1);
- if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL);
- }
- }
-}
static void
gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range)
range->col0 = MIN (range->col0, sheet->range.col0);
range->coli = MAX (range->coli, sheet->range.coli);
- range->row0 = MAX (range->row0, MIN_VISIBLE_ROW (sheet));
- range->rowi = MIN (range->rowi, MAX_VISIBLE_ROW (sheet));
- range->col0 = MAX (range->col0, MIN_VISIBLE_COLUMN (sheet));
- range->coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet));
+ range->row0 = MAX (range->row0, min_visible_row (sheet));
+ range->rowi = MIN (range->rowi, max_visible_row (sheet));
+ range->col0 = MAX (range->col0, min_visible_column (sheet));
+ range->coli = MIN (range->coli, max_visible_column (sheet));
- aux_range.row0 = MAX (new_range.row0, MIN_VISIBLE_ROW (sheet));
- aux_range.rowi = MIN (new_range.rowi, MAX_VISIBLE_ROW (sheet));
- aux_range.col0 = MAX (new_range.col0, MIN_VISIBLE_COLUMN (sheet));
- aux_range.coli = MIN (new_range.coli, MAX_VISIBLE_COLUMN (sheet));
+ aux_range.row0 = MAX (new_range.row0, min_visible_row (sheet));
+ aux_range.rowi = MIN (new_range.rowi, max_visible_row (sheet));
+ aux_range.col0 = MAX (new_range.col0, min_visible_column (sheet));
+ aux_range.coli = MIN (new_range.coli, max_visible_column (sheet));
for (i = range->row0; i <= range->rowi; i++)
{
j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE;
if (state == GTK_STATE_SELECTED && selected &&
- xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i) &&
(i == sheet->range.row0 || i == sheet->range.rowi ||
j == sheet->range.col0 || j == sheet->range.coli ||
i == new_range.row0 || i == new_range.rowi ||
if (mask1 != mask2)
{
- x = COLUMN_LEFT_XPIXEL (sheet, j);
- y = ROW_TOP_YPIXEL (sheet, i);
- width = COLUMN_LEFT_XPIXEL (sheet, j)- x+
- xxx_column_width (sheet, j);
- height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i);
+ x = psppire_axis_start_pixel (sheet->haxis, j);
+ y = psppire_axis_start_pixel (sheet->vaxis, i);
+ width = psppire_axis_start_pixel (sheet->haxis, j)- x+
+ psppire_axis_unit_size (sheet->haxis, j);
+ height = psppire_axis_start_pixel (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i);
if (i == sheet->range.row0)
{
}
if (j == sheet->range.coli) width = width + 3;
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x + 1,
- y + 1,
- x + 1,
- y + 1,
- width,
- height);
-
if (i != sheet->active_cell.row || j != sheet->active_cell.col)
{
- x = COLUMN_LEFT_XPIXEL (sheet, j);
- y = ROW_TOP_YPIXEL (sheet, i);
- width = COLUMN_LEFT_XPIXEL (sheet, j)- x+
- xxx_column_width (sheet, j);
+ x = psppire_axis_start_pixel (sheet->haxis, j);
+ y = psppire_axis_start_pixel (sheet->vaxis, i);
+ width = psppire_axis_start_pixel (sheet->haxis, j)- x+
+ psppire_axis_unit_size (sheet->haxis, j);
- height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i);
+ height = psppire_axis_start_pixel (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i);
if (i == new_range.row0)
{
selected= (i <= new_range.rowi && i >= new_range.row0 &&
j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE;
- if (state == GTK_STATE_SELECTED && !selected &&
- xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i))
+ if (state == GTK_STATE_SELECTED && !selected)
{
- x = COLUMN_LEFT_XPIXEL (sheet, j);
- y = ROW_TOP_YPIXEL (sheet, i);
- width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ xxx_column_width (sheet, j);
- height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i);
+ x = psppire_axis_start_pixel (sheet->haxis, j);
+ y = psppire_axis_start_pixel (sheet->vaxis, i);
+ width = psppire_axis_start_pixel (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j);
+ height = psppire_axis_start_pixel (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i);
if (i == sheet->range.row0)
{
}
if (j == sheet->range.coli) width = width + 3;
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x + 1,
- y + 1,
- x + 1,
- y + 1,
- width,
- height);
}
}
}
j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE;
if (state != GTK_STATE_SELECTED && selected &&
- xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i) &&
(i != sheet->active_cell.row || j != sheet->active_cell.col))
{
- x = COLUMN_LEFT_XPIXEL (sheet, j);
- y = ROW_TOP_YPIXEL (sheet, i);
- width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ xxx_column_width (sheet, j);
- height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i);
+ x = psppire_axis_start_pixel (sheet->haxis, j);
+ y = psppire_axis_start_pixel (sheet->vaxis, i);
+ width = psppire_axis_start_pixel (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j);
+ height = psppire_axis_start_pixel (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i);
if (i == new_range.row0)
{
{
for (j = aux_range.col0; j <= aux_range.coli; j++)
{
+ state = gtk_sheet_cell_get_state (sheet, i, j);
- if (xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i))
- {
-
- state = gtk_sheet_cell_get_state (sheet, i, j);
-
- mask1 = i == sheet->range.row0 ? 1 : 0;
- mask1 = i == sheet->range.rowi ? mask1 + 2 : mask1;
- mask1 = j == sheet->range.col0 ? mask1 + 4 : mask1;
- mask1 = j == sheet->range.coli ? mask1 + 8 : mask1;
-
- mask2 = i == new_range.row0 ? 1 : 0;
- mask2 = i == new_range.rowi ? mask2 + 2 : mask2;
- mask2 = j == new_range.col0 ? mask2 + 4 : mask2;
- mask2 = j == new_range.coli ? mask2 + 8 : mask2;
- if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED))
- {
- x = COLUMN_LEFT_XPIXEL (sheet, j);
- y = ROW_TOP_YPIXEL (sheet, i);
- width = xxx_column_width (sheet, j);
- height = yyy_row_height (sheet, i);
- if (mask2 & 1)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x + 1, y - 1,
- width, 3);
-
-
- if (mask2 & 2)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x + 1, y + height - 1,
- width, 3);
-
- if (mask2 & 4)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x - 1, y + 1,
- 3, height);
-
-
- if (mask2 & 8)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x + width - 1, y + 1,
- 3, height);
-
-
-
- }
+ mask1 = i == sheet->range.row0 ? 1 : 0;
+ mask1 = i == sheet->range.rowi ? mask1 + 2 : mask1;
+ mask1 = j == sheet->range.col0 ? mask1 + 4 : mask1;
+ mask1 = j == sheet->range.coli ? mask1 + 8 : mask1;
+ mask2 = i == new_range.row0 ? 1 : 0;
+ mask2 = i == new_range.rowi ? mask2 + 2 : mask2;
+ mask2 = j == new_range.col0 ? mask2 + 4 : mask2;
+ mask2 = j == new_range.coli ? mask2 + 8 : mask2;
+ if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED))
+ {
+ x = psppire_axis_start_pixel (sheet->haxis, j);
+ y = psppire_axis_start_pixel (sheet->vaxis, i);
+ width = psppire_axis_unit_size (sheet->haxis, j);
+ height = psppire_axis_unit_size (sheet->vaxis, i);
+ if (mask2 & 1)
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ TRUE,
+ x + 1, y - 1,
+ width, 3);
+
+
+ if (mask2 & 2)
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ TRUE,
+ x + 1, y + height - 1,
+ width, 3);
+
+ if (mask2 & 4)
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ TRUE,
+ x - 1, y + 1,
+ 3, height);
+
+
+ if (mask2 & 8)
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ TRUE,
+ x + width - 1, y + 1,
+ 3, height);
}
-
}
}
-
*range = new_range;
- gtk_sheet_draw_corners (sheet, new_range);
-
}
+
+
static void
gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange new_range)
{
- GtkWidget *widget;
GdkRectangle area;
- gint i;
- gint x, y, width, height;
-
- widget = GTK_WIDGET (sheet);
- x = COLUMN_LEFT_XPIXEL (sheet, new_range.col0);
- y = ROW_TOP_YPIXEL (sheet, new_range.row0);
- width = COLUMN_LEFT_XPIXEL (sheet, new_range.coli) - x +
- xxx_column_width (sheet, new_range.coli);
+ rectangle_from_range (sheet, &new_range, &area);
- height = ROW_TOP_YPIXEL (sheet, new_range.rowi) - y +
- yyy_row_height (sheet, new_range.rowi);
-
- area.x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet));
- area.y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet));
- area.width = sheet->sheet_window_width;
- area.height = sheet->sheet_window_height;
-
- if (x < 0)
- {
- width = width + x;
- x = 0;
- }
- if (width > area.width) width = area.width + 10;
- if (y < 0)
- {
- height = height + y;
- y = 0;
- }
- if (height > area.height) height = area.height + 10;
-
- gdk_gc_set_clip_rectangle (sheet->xor_gc, &area);
-
- for (i = -1; i <= 1; ++i)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- FALSE,
- x + i,
- y + i,
- width - 2 * i,
- height - 2 * i);
-
- gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL);
-
-
- gtk_sheet_draw_corners (sheet, new_range);
-}
-
-static void
-gtk_sheet_draw_corners (GtkSheet *sheet, GtkSheetRange range)
-{
- gint x, y;
- guint width = 1;
-
- if (gtk_sheet_cell_isvisible (sheet, range.row0, range.col0))
- {
- x = COLUMN_LEFT_XPIXEL (sheet, range.col0);
- y = ROW_TOP_YPIXEL (sheet, range.row0);
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x - 1,
- y - 1,
- x - 1,
- y - 1,
- 3,
- 3);
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x - 1, y - 1,
- 3, 3);
- }
-
- if (gtk_sheet_cell_isvisible (sheet, range.row0, range.coli) ||
- sheet->state == GTK_SHEET_COLUMN_SELECTED)
- {
- x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+
- xxx_column_width (sheet, range.coli);
- y = ROW_TOP_YPIXEL (sheet, range.row0);
- width = 1;
- if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- {
- y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet))+3;
- width = 3;
- }
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x - width,
- y - width,
- x - width,
- y - width,
- 2 * width + 1,
- 2 * width + 1);
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x - width + width / 2, y - width + width / 2,
- 2 + width, 2 + width);
- }
-
- if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.col0) ||
- sheet->state == GTK_SHEET_ROW_SELECTED)
- {
- x = COLUMN_LEFT_XPIXEL (sheet, range.col0);
- y = ROW_TOP_YPIXEL (sheet, range.rowi)+
- yyy_row_height (sheet, range.rowi);
- width = 1;
- if (sheet->state == GTK_SHEET_ROW_SELECTED)
- {
- x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet))+3;
- width = 3;
- }
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x - width,
- y - width,
- x - width,
- y - width,
- 2 * width + 1,
- 2 * width + 1);
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x - width + width / 2, y - width + width / 2,
- 2 + width, 2 + width);
- }
-
- if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.coli))
- {
- x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+
- xxx_column_width (sheet, range.coli);
- y = ROW_TOP_YPIXEL (sheet, range.rowi)+
- yyy_row_height (sheet, range.rowi);
- width = 1;
- if (sheet->state == GTK_SHEET_RANGE_SELECTED) width = 3;
- if (sheet->state == GTK_SHEET_NORMAL) width = 3;
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- x - width,
- y - width,
- x - width,
- y - width,
- 2 * width + 1,
- 2 * width + 1);
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- TRUE,
- x - width + width / 2, y - width + width / 2,
- 2 + width, 2 + width);
-
- }
-
-}
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ FALSE,
+ area.x, area.y,
+ area.width, area.height);
+}
static void
-gtk_sheet_real_select_range (GtkSheet * sheet,
- const GtkSheetRange * range)
+gtk_sheet_real_select_range (GtkSheet *sheet,
+ const GtkSheetRange *range)
{
gint state;
state = sheet->state;
+#if 0
if (range->coli != sheet->range.coli || range->col0 != sheet->range.col0 ||
range->rowi != sheet->range.rowi || range->row0 != sheet->range.row0)
{
}
else
{
- gtk_sheet_draw_backing_pixmap (sheet, sheet->range);
gtk_sheet_range_draw_selection (sheet, sheet->range);
}
+#endif
gtk_sheet_update_primary_selection (sheet);
void
-gtk_sheet_get_selected_range (GtkSheet *sheet,
- GtkSheetRange *range)
+gtk_sheet_get_selected_range (GtkSheet *sheet, GtkSheetRange *range)
{
g_return_if_fail (sheet != NULL);
*range = sheet->range;
void
-gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range)
+gtk_sheet_select_range (GtkSheet *sheet, const GtkSheetRange *range)
{
g_return_if_fail (sheet != NULL);
if (sheet->state != GTK_SHEET_NORMAL)
gtk_sheet_real_unselect_range (sheet, NULL);
- else
- gtk_sheet_deactivate_cell (sheet);
sheet->range.row0 = range->row0;
sheet->range.rowi = range->rowi;
sheet->state = GTK_SHEET_RANGE_SELECTED;
gtk_sheet_real_select_range (sheet, NULL);
-
}
void
-gtk_sheet_unselect_range (GtkSheet * sheet)
+gtk_sheet_unselect_range (GtkSheet *sheet)
{
if (! GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
return;
gtk_sheet_real_unselect_range (sheet, NULL);
sheet->state = GTK_STATE_NORMAL;
- gtk_sheet_activate_cell (sheet,
- sheet->active_cell.row, sheet->active_cell.col);
+ change_active_cell (sheet,
+ sheet->active_cell.row, sheet->active_cell.col);
}
static void
-gtk_sheet_real_unselect_range (GtkSheet * sheet,
+gtk_sheet_real_unselect_range (GtkSheet *sheet,
const GtkSheetRange *range)
{
g_return_if_fail (sheet != NULL);
g_signal_emit (sheet, sheet_signals[SELECT_COLUMN], 0, -1);
g_signal_emit (sheet, sheet_signals[SELECT_ROW], 0, -1);
- if (gtk_sheet_range_isvisible (sheet, *range))
- gtk_sheet_draw_backing_pixmap (sheet, *range);
-
sheet->range.row0 = -1;
sheet->range.rowi = -1;
sheet->range.col0 = -1;
sheet->range.coli = -1;
-
- gtk_sheet_position_children (sheet);
}
static gint
-gtk_sheet_expose (GtkWidget * widget,
- GdkEventExpose * event)
+gtk_sheet_expose (GtkWidget *widget,
+ GdkEventExpose *event)
{
GtkSheet *sheet;
GtkSheetRange range;
g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
-
sheet = GTK_SHEET (widget);
- if (GTK_WIDGET_DRAWABLE (widget))
+ if (!GTK_WIDGET_DRAWABLE (widget))
+ return FALSE;
+
+ /* exposure events on the sheet */
+ if (event->window == sheet->row_title_window &&
+ sheet->row_titles_visible)
{
- range.row0 = ROW_FROM_YPIXEL (sheet, event->area.y);
- range.col0 = COLUMN_FROM_XPIXEL (sheet, event->area.x);
- range.rowi = ROW_FROM_YPIXEL (sheet, event->area.y + event->area.height);
- range.coli = COLUMN_FROM_XPIXEL (sheet, event->area.x + event->area.width);
-
- /* exposure events on the sheet */
- if (event->window == sheet->row_title_window &&
- sheet->row_titles_visible)
- {
- gint i;
- for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++)
- gtk_sheet_row_title_button_draw (sheet, i);
- }
+ draw_row_title_buttons_range (sheet,
+ min_visible_row (sheet),
+ max_visible_row (sheet));
+ }
- if (event->window == sheet->column_title_window &&
- sheet->column_titles_visible)
- {
- gint i;
- for (i = MIN_VISIBLE_COLUMN (sheet); i <= MAX_VISIBLE_COLUMN (sheet); i++)
- gtk_sheet_column_title_button_draw (sheet, i);
- }
+ if (event->window == sheet->column_title_window &&
+ sheet->column_titles_visible)
+ {
+ draw_column_title_buttons_range (sheet,
+ min_visible_column (sheet),
+ max_visible_column (sheet));
+ }
+
+
+ {
+ gint y = event->area.y + sheet->vadjustment->value;
+ gint x = event->area.x + sheet->hadjustment->value;
+
+ if ( sheet->column_titles_visible)
+ y -= sheet->column_title_area.height;
+
+ if ( sheet->row_titles_visible)
+ x -= sheet->row_title_area.width;
+
+ maximize_int (&x, 0);
+ maximize_int (&y, 0);
- if (event->window == sheet->sheet_window)
+ range.row0 = row_from_ypixel (sheet, y);
+
+ range.rowi = row_from_ypixel (sheet, y + event->area.height);
+
+ range.col0 = column_from_xpixel (sheet, x);
+
+ range.coli = column_from_xpixel (sheet, x + event->area.width);
+ }
+
+ if (event->window == sheet->sheet_window)
+ {
+ gtk_sheet_range_draw (sheet, &range);
+
+ if (sheet->state != GTK_SHEET_NORMAL)
{
- gtk_sheet_draw_backing_pixmap (sheet, range);
+ if (gtk_sheet_range_isvisible (sheet, &sheet->range))
+ gtk_sheet_range_draw (sheet, &sheet->range);
- if (sheet->state != GTK_SHEET_NORMAL)
- {
- if (gtk_sheet_range_isvisible (sheet, sheet->range))
- gtk_sheet_draw_backing_pixmap (sheet, sheet->range);
- if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet))
- gtk_sheet_draw_backing_pixmap (sheet, sheet->drag_range);
-
- if (gtk_sheet_range_isvisible (sheet, sheet->range))
- gtk_sheet_range_draw_selection (sheet, sheet->range);
- if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet))
- draw_xor_rectangle (sheet, sheet->drag_range);
- }
+ if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet))
+ gtk_sheet_range_draw (sheet, &sheet->drag_range);
- if ((!GTK_SHEET_IN_XDRAG (sheet)) && (!GTK_SHEET_IN_YDRAG (sheet)))
- {
- if (sheet->state == GTK_SHEET_NORMAL)
- gtk_sheet_draw_active_cell (sheet);
- }
+ if (gtk_sheet_range_isvisible (sheet, &sheet->range))
+ gtk_sheet_range_draw_selection (sheet, sheet->range);
+ if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet))
+ draw_xor_rectangle (sheet, sheet->drag_range);
}
- }
- if (sheet->state != GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION (sheet))
- gtk_widget_grab_focus (GTK_WIDGET (sheet));
+ }
(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+ if (event->window == sheet->sheet_window)
+ {
+ if ((!GTK_SHEET_IN_XDRAG (sheet)) && (!GTK_SHEET_IN_YDRAG (sheet)))
+ {
+ if (sheet->state == GTK_SHEET_NORMAL)
+ gtk_sheet_draw_active_cell (sheet);
+ }
+ }
+
return FALSE;
}
static gboolean
-gtk_sheet_button_press (GtkWidget * widget,
- GdkEventButton * event)
+gtk_sheet_button_press (GtkWidget *widget,
+ GdkEventButton *event)
{
GtkSheet *sheet;
GdkModifierType mods;
- gint x, y, row, column;
+ gint x, y;
+ gint row, column;
gboolean veto;
g_return_val_if_fail (widget != NULL, FALSE);
if (event->window == sheet->column_title_window)
{
+ sheet->x_drag = event->x;
g_signal_emit (sheet,
sheet_signals[BUTTON_EVENT_COLUMN], 0,
column, event);
- if ( event->type == GDK_2BUTTON_PRESS && event->button == 1)
- g_signal_emit (sheet,
- sheet_signals[DOUBLE_CLICK_COLUMN], 0, column);
-
+ if (g_sheet_model_get_column_sensitivity (sheet->model, column))
+ {
+ if ( event->type == GDK_2BUTTON_PRESS && event->button == 1)
+ g_signal_emit (sheet,
+ sheet_signals[DOUBLE_CLICK_COLUMN], 0, column);
+ }
}
else if (event->window == sheet->row_title_window)
{
sheet_signals[BUTTON_EVENT_ROW], 0,
row, event);
- if ( event->type == GDK_2BUTTON_PRESS && event->button == 1)
- g_signal_emit (sheet,
- sheet_signals[DOUBLE_CLICK_ROW], 0, row);
+ if (g_sheet_model_get_row_sensitivity (sheet->model, row))
+ {
+ if ( event->type == GDK_2BUTTON_PRESS && event->button == 1)
+ g_signal_emit (sheet,
+ sheet_signals[DOUBLE_CLICK_ROW], 0, row);
+ }
}
-
gdk_window_get_pointer (widget->window, NULL, NULL, &mods);
if (! (mods & GDK_BUTTON1_MASK)) return TRUE;
/* press on resize windows */
- if (event->window == sheet->column_title_window &&
- gtk_sheet_columns_resizable (sheet))
+ if (event->window == sheet->column_title_window)
{
- gtk_widget_get_pointer (widget, &sheet->x_drag, NULL);
- if (POSSIBLE_XDRAG (sheet, sheet->x_drag, &sheet->drag_cell.col))
+ sheet->x_drag = event->x;
+
+ if (on_column_boundary (sheet, sheet->x_drag, &sheet->drag_cell.col))
{
- guint req;
- if (event->type == GDK_2BUTTON_PRESS)
- {
- gtk_sheet_autoresize_column (sheet, sheet->drag_cell.col);
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
- return TRUE;
- }
- gtk_sheet_column_size_request (sheet, sheet->drag_cell.col, &req);
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
gdk_pointer_grab (sheet->column_title_window, FALSE,
GDK_POINTER_MOTION_HINT_MASK |
}
}
- if (event->window == sheet->row_title_window && gtk_sheet_rows_resizable (sheet))
+ if (event->window == sheet->row_title_window)
{
- gtk_widget_get_pointer (widget, NULL, &sheet->y_drag);
+ sheet->y_drag = event->y;
- if (POSSIBLE_YDRAG (sheet, sheet->y_drag, &sheet->drag_cell.row))
+ if (on_row_boundary (sheet, sheet->y_drag, &sheet->drag_cell.row))
{
- guint req;
- gtk_sheet_row_size_request (sheet, sheet->drag_cell.row, &req);
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_YDRAG);
gdk_pointer_grab (sheet->row_title_window, FALSE,
GDK_POINTER_MOTION_HINT_MASK |
NULL, NULL, event->time);
gtk_grab_add (GTK_WIDGET (sheet));
- /* This seems to be a kludge to work around a problem where the sheet
- scrolls to another position. The timeout scrolls it back to its
- original posn. JMD 3 July 2007
- */
- gtk_widget_grab_focus (GTK_WIDGET (sheet));
-
if (sheet->selection_mode != GTK_SELECTION_SINGLE &&
sheet->selection_mode != GTK_SELECTION_NONE &&
sheet->cursor_drag->type == GDK_SIZING &&
{
row = sheet->active_cell.row;
column = sheet->active_cell.col;
- gtk_sheet_deactivate_cell (sheet);
sheet->active_cell.row = row;
sheet->active_cell.col = column;
sheet->drag_range = sheet->range;
{
row = sheet->active_cell.row;
column = sheet->active_cell.col;
- gtk_sheet_deactivate_cell (sheet);
sheet->active_cell.row = row;
sheet->active_cell.col = column;
sheet->drag_range = sheet->range;
}
else
{
- gtk_sheet_click_cell (sheet, row, column, &veto);
+ veto = gtk_sheet_click_cell (sheet, row, column);
if (veto) GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
}
if (event->window == sheet->column_title_window)
{
gtk_widget_get_pointer (widget, &x, &y);
- column = COLUMN_FROM_XPIXEL (sheet, x);
+ if ( sheet->row_titles_visible)
+ x -= sheet->row_title_area.width;
- if (xxx_column_is_sensitive (sheet, column))
+ x += sheet->hadjustment->value;
+
+ column = column_from_xpixel (sheet, x);
+
+ if (g_sheet_model_get_column_sensitivity (sheet->model, column))
{
- gtk_sheet_click_cell (sheet, - 1, column, &veto);
+ veto = gtk_sheet_click_cell (sheet, -1, column);
gtk_grab_add (GTK_WIDGET (sheet));
- gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
}
if (event->window == sheet->row_title_window)
{
gtk_widget_get_pointer (widget, &x, &y);
- row = ROW_FROM_YPIXEL (sheet, y);
- if (yyy_row_is_sensitive (sheet, row))
+ if ( sheet->column_titles_visible)
+ y -= sheet->column_title_area.height;
+
+ y += sheet->vadjustment->value;
+
+ row = row_from_ypixel (sheet, y);
+ if (g_sheet_model_get_row_sensitivity (sheet->model, row))
{
- gtk_sheet_click_cell (sheet, row, - 1, &veto);
+ veto = gtk_sheet_click_cell (sheet, row, -1);
gtk_grab_add (GTK_WIDGET (sheet));
- gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
}
return TRUE;
}
-static void
-gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto)
+static gboolean
+gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column)
{
- *veto = TRUE;
+ GtkSheetCell cell;
+ gboolean forbid_move;
- if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet))
+ cell.row = row;
+ cell.col = column;
+
+ if (row >= psppire_axis_unit_count (sheet->vaxis)
+ || column >= psppire_axis_unit_count (sheet->haxis))
{
- *veto = FALSE;
- return;
+ return FALSE;
}
- if (column >= 0 && row >= 0)
- if (! xxx_column_is_visible (sheet, column) || !yyy_row_is_visible (sheet, row))
- {
- *veto = FALSE;
- return;
- }
-
- _gtkextra_signal_emit (GTK_OBJECT (sheet), sheet_signals[TRAVERSE],
- sheet->active_cell.row, sheet->active_cell.col,
- &row, &column, veto);
+ g_signal_emit (sheet, sheet_signals[TRAVERSE], 0,
+ &sheet->active_cell,
+ &cell,
+ &forbid_move);
- if (!*veto)
+ if (forbid_move)
{
- if (sheet->state == GTK_STATE_NORMAL) return;
+ if (sheet->state == GTK_STATE_NORMAL)
+ return FALSE;
row = sheet->active_cell.row;
column = sheet->active_cell.col;
- gtk_sheet_activate_cell (sheet, row, column);
- return;
+ change_active_cell (sheet, row, column);
+ return FALSE;
}
if (row == -1 && column >= 0)
{
- if (gtk_sheet_autoscroll (sheet))
- gtk_sheet_move_query (sheet, row, column);
gtk_sheet_select_column (sheet, column);
- return;
+ return TRUE;
}
+
if (column == -1 && row >= 0)
{
- if (gtk_sheet_autoscroll (sheet))
- gtk_sheet_move_query (sheet, row, column);
gtk_sheet_select_row (sheet, row);
- return;
+ return TRUE;
}
- if (row == - 1 && column == - 1)
+ if (row == -1 && column == -1)
{
sheet->range.row0 = 0;
sheet->range.col0 = 0;
- sheet->range.rowi = yyy_row_count (sheet) - 1;
- sheet->range.coli = xxx_column_count (sheet) - 1;
+ sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1;
+ sheet->range.coli =
+ psppire_axis_unit_count (sheet->haxis) - 1;
sheet->active_cell.row = 0;
sheet->active_cell.col = 0;
gtk_sheet_select_range (sheet, NULL);
- return;
+ return TRUE;
}
- if (row != -1 && column != -1)
+ if (sheet->state != GTK_SHEET_NORMAL)
{
- if (sheet->state != GTK_SHEET_NORMAL)
- {
- sheet->state = GTK_SHEET_NORMAL;
- gtk_sheet_real_unselect_range (sheet, NULL);
- }
- else
- {
- gtk_sheet_deactivate_cell (sheet);
- gtk_sheet_activate_cell (sheet, row, column);
- }
-
- if (gtk_sheet_autoscroll (sheet))
- gtk_sheet_move_query (sheet, row, column);
- sheet->active_cell.row = row;
- sheet->active_cell.col = column;
- sheet->selection_cell.row = row;
- sheet->selection_cell.col = column;
- sheet->range.row0 = row;
- sheet->range.col0 = column;
- sheet->range.rowi = row;
- sheet->range.coli = column;
sheet->state = GTK_SHEET_NORMAL;
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- gtk_sheet_draw_active_cell (sheet);
- return;
+ gtk_sheet_real_unselect_range (sheet, NULL);
+ }
+ else
+ {
+ change_active_cell (sheet, row, column);
}
- g_assert_not_reached ();
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
- sheet->active_cell.col);
+ sheet->active_cell.row = row;
+ sheet->active_cell.col = column;
+ sheet->selection_cell.row = row;
+ sheet->selection_cell.col = column;
+ sheet->range.row0 = row;
+ sheet->range.col0 = column;
+ sheet->range.rowi = row;
+ sheet->range.coli = column;
+ sheet->state = GTK_SHEET_NORMAL;
+ GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+
+ gtk_sheet_draw_active_cell (sheet);
+
+ gtk_widget_grab_focus (GTK_WIDGET (sheet->entry_widget));
+
+ return TRUE;
}
static gint
-gtk_sheet_button_release (GtkWidget * widget,
- GdkEventButton * event)
+gtk_sheet_button_release (GtkWidget *widget,
+ GdkEventButton *event)
{
- GtkSheet *sheet;
- gint x, y;
+ GdkDisplay *display = gtk_widget_get_display (widget);
- sheet = GTK_SHEET (widget);
+ GtkSheet *sheet = GTK_SHEET (widget);
/* release on resize windows */
if (GTK_SHEET_IN_XDRAG (sheet))
{
+ gint width;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG);
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- gtk_widget_get_pointer (widget, &x, NULL);
- gdk_pointer_ungrab (event->time);
+
+ gdk_display_pointer_ungrab (display, event->time);
draw_xor_vline (sheet);
- gtk_sheet_set_column_width (sheet, sheet->drag_cell.col,
- new_column_width (sheet, sheet->drag_cell.col, &x));
- sheet->old_hadjustment = -1.;
- g_signal_emit_by_name (sheet->hadjustment, "value_changed");
+ width = event->x -
+ psppire_axis_start_pixel (sheet->haxis, sheet->drag_cell.col)
+ + sheet->hadjustment->value;
+
+ set_column_width (sheet, sheet->drag_cell.col, width);
+
return TRUE;
}
if (GTK_SHEET_IN_YDRAG (sheet))
{
+ gint height;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_YDRAG);
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- gtk_widget_get_pointer (widget, NULL, &y);
- gdk_pointer_ungrab (event->time);
+
+ gdk_display_pointer_ungrab (display, event->time);
draw_xor_hline (sheet);
- gtk_sheet_set_row_height (sheet, sheet->drag_cell.row, new_row_height (sheet, sheet->drag_cell.row, &y));
- sheet->old_vadjustment = -1.;
- g_signal_emit_by_name (sheet->vadjustment, "value_changed");
+ height = event->y -
+ psppire_axis_start_pixel (sheet->vaxis, sheet->drag_cell.row) +
+ sheet->vadjustment->value;
+
+ set_row_height (sheet, sheet->drag_cell.row, height);
+
return TRUE;
}
-
if (GTK_SHEET_IN_DRAG (sheet))
{
GtkSheetRange old_range;
draw_xor_rectangle (sheet, sheet->drag_range);
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_DRAG);
- gdk_pointer_ungrab (event->time);
+ gdk_display_pointer_ungrab (display, event->time);
gtk_sheet_real_unselect_range (sheet, NULL);
GtkSheetRange old_range;
draw_xor_rectangle (sheet, sheet->drag_range);
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_RESIZE);
- gdk_pointer_ungrab (event->time);
+ gdk_display_pointer_ungrab (display, event->time);
gtk_sheet_real_unselect_range (sheet, NULL);
if (sheet->state == GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION (sheet))
{
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- gdk_pointer_ungrab (event->time);
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
+ gdk_display_pointer_ungrab (display, event->time);
+ change_active_cell (sheet, sheet->active_cell.row,
sheet->active_cell.col);
}
if (GTK_SHEET_IN_SELECTION)
- gdk_pointer_ungrab (event->time);
+ gdk_display_pointer_ungrab (display, event->time);
gtk_grab_remove (GTK_WIDGET (sheet));
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
return TRUE;
}
+\f
+
+
+
/* Shamelessly lifted from gtktooltips */
static gboolean
gtk_sheet_subtitle_paint_window (GtkWidget *tip_window)
return FALSE;
}
+static void
+destroy_hover_window (GtkSheetHoverTitle *h)
+{
+ gtk_widget_destroy (h->window);
+ g_free (h);
+}
+
static GtkSheetHoverTitle *
create_hover_window (void)
{
- GtkSheetHoverTitle *hw = malloc (sizeof (*hw));
+ GtkSheetHoverTitle *hw = g_malloc (sizeof (*hw));
hw->window = gtk_window_new (GTK_WINDOW_POPUP);
if ( ! subtitle )
return;
- if ( ! sheet->hover_window)
- {
- sheet->hover_window = create_hover_window ();
- gtk_widget_add_events (GTK_WIDGET (sheet), GDK_LEAVE_NOTIFY_MASK);
-
- g_signal_connect_swapped (sheet, "leave-notify-event",
- G_CALLBACK (gtk_widget_hide),
- sheet->hover_window->window);
- }
-
gtk_label_set_text (GTK_LABEL (sheet->hover_window->label),
subtitle);
if ( gtk_sheet_get_pixel_info (sheet, x, y, &row, &column) )
{
- if ( column == -1 && row == -1 )
- return FALSE;
-
- if ( column == -1)
+ if (sheet->row_title_under)
{
- GSheetRow *row_geo = sheet->row_geometry;
- gchar *text;
-
- text = g_sheet_row_get_subtitle (row_geo, row);
+ gchar *text = g_sheet_model_get_row_subtitle (sheet->model, row);
- show_subtitle (sheet, row, column, text);
+ show_subtitle (sheet, row, -1, text);
g_free (text);
}
- if ( row == -1)
+ if (sheet->column_title_under)
{
- GSheetColumn *col_geo = sheet->column_geometry;
- gchar *text;
+ gchar *text = g_sheet_model_get_column_subtitle (sheet->model,
+ column);
- text = g_sheet_column_get_subtitle (col_geo, column);
-
- show_subtitle (sheet, row, column, text );
+ show_subtitle (sheet, -1, column, text);
g_free (text);
}
return FALSE;
}
-static gint
-gtk_sheet_motion (GtkWidget * widget,
- GdkEventMotion * event)
+static gboolean
+gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event)
{
- GtkSheet *sheet;
+ GtkSheet *sheet = GTK_SHEET (widget);
GdkModifierType mods;
GdkCursorType new_cursor;
gint x, y;
gint row, column;
+ GdkDisplay *display;
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- sheet = GTK_SHEET (widget);
+ display = gtk_widget_get_display (widget);
/* selections on the sheet */
x = event->x;
y = event->y;
- if (!sheet->hover_window || ! GTK_WIDGET_VISIBLE (sheet->hover_window->window))
+ if (!GTK_WIDGET_VISIBLE (sheet->hover_window->window))
{
if ( sheet->motion_timer > 0 )
g_source_remove (sheet->motion_timer);
- sheet->motion_timer = g_timeout_add (TIMEOUT_HOVER, motion_timeout_callback, sheet);
+ sheet->motion_timer =
+ g_timeout_add (TIMEOUT_HOVER, motion_timeout_callback, sheet);
}
else
{
if ( gtk_sheet_get_pixel_info (sheet, wx, wy, &row, &column) )
{
- if ( row != sheet->hover_window->row || column != sheet->hover_window->column)
+ if ( row != sheet->hover_window->row ||
+ column != sheet->hover_window->column)
{
gtk_widget_hide (sheet->hover_window->window);
}
}
}
- if (event->window == sheet->column_title_window &&
- gtk_sheet_columns_resizable (sheet))
+ if (event->window == sheet->column_title_window)
{
- gtk_widget_get_pointer (widget, &x, &y);
if (!GTK_SHEET_IN_SELECTION (sheet) &&
- POSSIBLE_XDRAG (sheet, x, &column))
+ on_column_boundary (sheet, x, &column))
{
new_cursor = GDK_SB_H_DOUBLE_ARROW;
if (new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
+ sheet->cursor_drag =
+ gdk_cursor_new_for_display (display, new_cursor);
+
gdk_window_set_cursor (sheet->column_title_window,
sheet->cursor_drag);
}
new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
+ sheet->cursor_drag =
+ gdk_cursor_new_for_display (display, new_cursor);
gdk_window_set_cursor (sheet->column_title_window,
sheet->cursor_drag);
}
}
}
-
- if (event->window == sheet->row_title_window &&
- gtk_sheet_rows_resizable (sheet))
+ else if (event->window == sheet->row_title_window)
{
- gtk_widget_get_pointer (widget, &x, &y);
- if (!GTK_SHEET_IN_SELECTION (sheet) && POSSIBLE_YDRAG (sheet, y, &column))
+ if (!GTK_SHEET_IN_SELECTION (sheet) &&
+ on_row_boundary (sheet, y, &row))
{
new_cursor = GDK_SB_V_DOUBLE_ARROW;
if (new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_SB_V_DOUBLE_ARROW);
- gdk_window_set_cursor (sheet->row_title_window, sheet->cursor_drag);
+ sheet->cursor_drag =
+ gdk_cursor_new_for_display (display, new_cursor);
+ gdk_window_set_cursor (sheet->row_title_window,
+ sheet->cursor_drag);
}
}
else
new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
- gdk_window_set_cursor (sheet->row_title_window, sheet->cursor_drag);
+ sheet->cursor_drag =
+ gdk_cursor_new_for_display (display, new_cursor);
+ gdk_window_set_cursor (sheet->row_title_window,
+ sheet->cursor_drag);
}
}
}
new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_PLUS);
+ sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_PLUS);
gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag);
}
new_cursor = GDK_TOP_LEFT_ARROW;
if ( event->window == sheet->sheet_window &&
- ! (POSSIBLE_RESIZE (sheet, x, y, &row, &column) || GTK_SHEET_IN_RESIZE (sheet)) && (POSSIBLE_DRAG (sheet, x, y, &row, &column) || GTK_SHEET_IN_DRAG (sheet)) &&
-
+ ! (POSSIBLE_RESIZE (sheet, x, y, &row, &column) ||
+ GTK_SHEET_IN_RESIZE (sheet)) &&
+ (POSSIBLE_DRAG (sheet, x, y, &row, &column) ||
+ GTK_SHEET_IN_DRAG (sheet)) &&
new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
+ sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW);
gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag);
}
new_cursor != sheet->cursor_drag->type)
{
gdk_cursor_unref (sheet->cursor_drag);
- sheet->cursor_drag = gdk_cursor_new (GDK_SIZING);
+ sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_SIZING);
gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag);
}
if (GTK_SHEET_IN_XDRAG (sheet))
{
- if (event->is_hint || event->window != widget->window)
- gtk_widget_get_pointer (widget, &x, NULL);
- else
- x = event->x;
-
- new_column_width (sheet, sheet->drag_cell.col, &x);
- if (x != sheet->x_drag)
+ if (event->x != sheet->x_drag)
{
draw_xor_vline (sheet);
- sheet->x_drag = x;
+ sheet->x_drag = event->x;
draw_xor_vline (sheet);
}
+
return TRUE;
}
if (GTK_SHEET_IN_YDRAG (sheet))
{
- if (event->is_hint || event->window != widget->window)
- gtk_widget_get_pointer (widget, NULL, &y);
- else
- y = event->y;
-
- new_row_height (sheet, sheet->drag_cell.row, &y);
- if (y != sheet->y_drag)
+ if (event->y != sheet->y_drag)
{
draw_xor_hline (sheet);
- sheet->y_drag = y;
+ sheet->y_drag = event->y;
draw_xor_hline (sheet);
}
+
return TRUE;
}
if (GTK_SHEET_IN_DRAG (sheet))
{
GtkSheetRange aux;
- column = COLUMN_FROM_XPIXEL (sheet, x)- sheet->drag_cell.col;
- row = ROW_FROM_YPIXEL (sheet, y)- sheet->drag_cell.row;
+ column = column_from_xpixel (sheet, x)- sheet->drag_cell.col;
+ row = row_from_ypixel (sheet, y) - sheet->drag_cell.row;
if (sheet->state == GTK_SHEET_COLUMN_SELECTED) row = 0;
if (sheet->state == GTK_SHEET_ROW_SELECTED) column = 0;
sheet->x_drag = x;
sheet->y_drag = y;
aux = sheet->range;
- if (aux.row0 + row >= 0 && aux.rowi + row < yyy_row_count (sheet) &&
- aux.col0 + column >= 0 && aux.coli + column < xxx_column_count (sheet))
+ if (aux.row0 + row >= 0 && aux.rowi + row < psppire_axis_unit_count (sheet->vaxis) &&
+ aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis))
{
aux = sheet->drag_range;
sheet->drag_range.row0 = sheet->range.row0 + row;
GtkSheetRange aux;
gint v_h, current_col, current_row, col_threshold, row_threshold;
v_h = 1;
+ if (abs (x - psppire_axis_start_pixel (sheet->haxis, sheet->drag_cell.col)) >
+ abs (y - psppire_axis_start_pixel (sheet->vaxis, sheet->drag_cell.row))) v_h = 2;
- if (abs (x - COLUMN_LEFT_XPIXEL (sheet, sheet->drag_cell.col)) >
- abs (y - ROW_TOP_YPIXEL (sheet, sheet->drag_cell.row))) v_h = 2;
-
- current_col = COLUMN_FROM_XPIXEL (sheet, x);
- current_row = ROW_FROM_YPIXEL (sheet, y);
+ current_col = column_from_xpixel (sheet, x);
+ current_row = row_from_ypixel (sheet, y);
column = current_col - sheet->drag_cell.col;
row = current_row - sheet->drag_cell.row;
/*use half of column width resp. row height as threshold to
expand selection*/
- col_threshold = COLUMN_LEFT_XPIXEL (sheet, current_col) +
- xxx_column_width (sheet, current_col) / 2;
+ col_threshold = psppire_axis_start_pixel (sheet->haxis, current_col) +
+ psppire_axis_unit_size (sheet->haxis, current_col) / 2;
if (column > 0)
{
if (x < col_threshold)
if (x > col_threshold)
column +=1;
}
- row_threshold = ROW_TOP_YPIXEL (sheet, current_row) +
- yyy_row_height (sheet, current_row)/2;
+ row_threshold = psppire_axis_start_pixel (sheet->vaxis, current_row) +
+ psppire_axis_unit_size (sheet->vaxis, current_row)/2;
if (row > 0)
{
if (y < row_threshold)
else
row = 0;
- if (aux.row0 + row >= 0 && aux.rowi + row < yyy_row_count (sheet) &&
- aux.col0 + column >= 0 && aux.coli + column < xxx_column_count (sheet))
+ if (aux.row0 + row >= 0 && aux.rowi + row < psppire_axis_unit_count (sheet->vaxis) &&
+ aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis))
{
aux = sheet->drag_range;
sheet->drag_range = sheet->range;
}
static gboolean
-gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column)
+gtk_sheet_crossing_notify (GtkWidget *widget,
+ GdkEventCrossing *event)
{
- gint row_move, column_move;
- gfloat row_align, col_align;
- guint height, width;
- gint new_row = row;
- gint new_col = column;
-
- row_move = FALSE;
- column_move = FALSE;
- row_align = -1.;
- col_align = -1.;
-
- height = sheet->sheet_window_height;
- width = sheet->sheet_window_width;
-
- if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED)
- {
- row_align = 1.;
- new_row = MIN (yyy_row_count (sheet) - 1, row + 1);
- row_move = TRUE;
- if (MAX_VISIBLE_ROW (sheet) == yyy_row_count (sheet) - 1 &&
- ROW_TOP_YPIXEL (sheet, yyy_row_count (sheet)- 1) +
- yyy_row_height (sheet, yyy_row_count (sheet)- 1) < height)
- {
- row_move = FALSE;
- row_align = -1.;
- }
- }
- if (row < MIN_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED)
- {
- row_align= 0.;
- row_move = TRUE;
- }
- if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED)
- {
- col_align = 1.;
- new_col = MIN (xxx_column_count (sheet) - 1, column + 1);
- column_move = TRUE;
- if (MAX_VISIBLE_COLUMN (sheet) == (xxx_column_count (sheet) - 1) &&
- COLUMN_LEFT_XPIXEL (sheet, xxx_column_count (sheet) - 1) +
- xxx_column_width (sheet, xxx_column_count (sheet) - 1) < width)
- {
- column_move = FALSE;
- col_align = -1.;
- }
- }
- if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED)
- {
- col_align = 0.;
- column_move = TRUE;
- }
+ GtkSheet *sheet = GTK_SHEET (widget);
- if (row_move || column_move)
- {
- gtk_sheet_moveto (sheet, new_row, new_col, row_align, col_align);
- }
+ if (event->window == sheet->column_title_window)
+ sheet->column_title_under = event->type == GDK_ENTER_NOTIFY;
+ else if (event->window == sheet->row_title_window)
+ sheet->row_title_under = event->type == GDK_ENTER_NOTIFY;
- return (row_move || column_move);
+ return TRUE;
}
static void
if (sheet->selection_mode == GTK_SELECTION_SINGLE) return;
- gtk_sheet_move_query (sheet, row, column);
gtk_widget_grab_focus (GTK_WIDGET (sheet));
if (GTK_SHEET_IN_DRAG (sheet)) return;
switch (sheet->state)
{
case GTK_SHEET_ROW_SELECTED:
- column = xxx_column_count (sheet) - 1;
+ column = psppire_axis_unit_count (sheet->haxis) - 1;
break;
case GTK_SHEET_COLUMN_SELECTED:
- row = yyy_row_count (sheet) - 1;
+ row = psppire_axis_unit_count (sheet->vaxis) - 1;
break;
case GTK_SHEET_NORMAL:
sheet->state = GTK_SHEET_RANGE_SELECTED;
sheet->range.row0 = r;
sheet->range.coli = c;
sheet->range.rowi = r;
- gdk_draw_drawable (sheet->sheet_window,
- GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL],
- sheet->pixmap,
- COLUMN_LEFT_XPIXEL (sheet, c)- 1,
- ROW_TOP_YPIXEL (sheet, r)- 1,
- COLUMN_LEFT_XPIXEL (sheet, c)- 1,
- ROW_TOP_YPIXEL (sheet, r)- 1,
- xxx_column_width (sheet, c)+4,
- yyy_row_height (sheet, r)+4);
gtk_sheet_range_draw_selection (sheet, sheet->range);
case GTK_SHEET_RANGE_SELECTED:
sheet->state = GTK_SHEET_RANGE_SELECTED;
return focus;
}
-static gint
-gtk_sheet_key_press (GtkWidget *widget,
- GdkEventKey *key)
-{
- GtkSheet *sheet;
- gint row, col;
- gint state;
- gboolean extend_selection = FALSE;
- gboolean force_move = FALSE;
- gboolean in_selection = FALSE;
- gboolean veto = TRUE;
- gint scroll = 1;
- sheet = GTK_SHEET (widget);
+/* Number of rows in a step-increment */
+#define ROWS_PER_STEP 1
- if (key->state & GDK_CONTROL_MASK || key->keyval == GDK_Control_L ||
- key->keyval == GDK_Control_R) return FALSE;
- extend_selection = (key->state & GDK_SHIFT_MASK) || key->keyval == GDK_Shift_L
- || key->keyval == GDK_Shift_R;
+static void
+page_vertical (GtkSheet *sheet, GtkScrollType dir)
+{
+ gint old_row = sheet->active_cell.row ;
+ glong vpixel = psppire_axis_start_pixel (sheet->vaxis, old_row);
- state = sheet->state;
- in_selection = GTK_SHEET_IN_SELECTION (sheet);
- GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+ gint new_row;
- switch (key->keyval)
+ vpixel -= psppire_axis_start_pixel (sheet->vaxis,
+ min_visible_row (sheet));
+
+ switch ( dir)
{
- case GDK_Return: case GDK_KP_Enter:
- if (sheet->state == GTK_SHEET_NORMAL &&
- !GTK_SHEET_IN_SELECTION (sheet))
- g_signal_stop_emission_by_name (gtk_sheet_get_entry (sheet),
- "key-press-event");
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet)- 1;
- if (sheet->state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet);
- if (row < yyy_row_count (sheet) - 1)
- {
- row = row + scroll;
- while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1)
- row++;
- }
- gtk_sheet_click_cell (sheet, row, col, &veto);
- extend_selection = FALSE;
+ case GTK_SCROLL_PAGE_DOWN:
+ gtk_adjustment_set_value (sheet->vadjustment,
+ sheet->vadjustment->value +
+ sheet->vadjustment->page_increment);
break;
- case GDK_ISO_Left_Tab:
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- if (sheet->state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet)- 1;
- if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet);
- if (col > 0)
- {
- col = col - scroll;
- while (! xxx_column_is_visible (sheet, col) && col > 0) col--;
- col = MAX (0, col);
- }
- gtk_sheet_click_cell (sheet, row, col, &veto);
- extend_selection = FALSE;
+ case GTK_SCROLL_PAGE_UP:
+ gtk_adjustment_set_value (sheet->vadjustment,
+ sheet->vadjustment->value -
+ sheet->vadjustment->page_increment);
+
break;
- case GDK_Tab:
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- if (sheet->state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet)- 1;
- if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet);
- if (col < xxx_column_count (sheet) - 1)
- {
- col = col + scroll;
- while (! xxx_column_is_visible (sheet, col) &&
- col < xxx_column_count (sheet) - 1)
- col++;
- }
- gtk_sheet_click_cell (sheet, row, col, &veto);
- extend_selection = FALSE;
+ default:
+ g_assert_not_reached ();
break;
- case GDK_Page_Up:
- scroll = MAX_VISIBLE_ROW (sheet)- MIN_VISIBLE_ROW (sheet)+1;
- case GDK_Up:
- if (extend_selection)
- {
- if (state == GTK_STATE_NORMAL)
- {
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- gtk_sheet_click_cell (sheet, row, col, &veto);
- if (!veto) break;
- }
- if (sheet->selection_cell.row > 0)
- {
- row = sheet->selection_cell.row - scroll;
- while (!yyy_row_is_visible (sheet, row) && row > 0) row--;
- row = MAX (0, row);
- gtk_sheet_extend_selection (sheet, row, sheet->selection_cell.col);
- }
- return TRUE;
- }
- col = sheet->active_cell.col;
- row = sheet->active_cell.row;
- if (state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet);
- if (state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet);
- row = row - scroll;
- while (!yyy_row_is_visible (sheet, row) && row > 0) row--;
- row = MAX (0, row);
- gtk_sheet_click_cell (sheet, row, col, &veto);
- extend_selection = FALSE;
+ }
+
+
+ vpixel += psppire_axis_start_pixel (sheet->vaxis,
+ min_visible_row (sheet));
+
+ new_row = row_from_ypixel (sheet, vpixel);
+
+ change_active_cell (sheet, new_row,
+ sheet->active_cell.col);
+}
+
+
+static void
+step_sheet (GtkSheet *sheet, GtkScrollType dir)
+{
+ gint current_row = sheet->active_cell.row;
+ gint current_col = sheet->active_cell.col;
+ GtkSheetCell new_cell ;
+ gboolean forbidden = FALSE;
+
+ new_cell.row = current_row;
+ new_cell.col = current_col;
+
+ switch ( dir)
+ {
+ case GTK_SCROLL_STEP_DOWN:
+ new_cell.row++;
break;
- case GDK_Page_Down:
- scroll = MAX_VISIBLE_ROW (sheet)- MIN_VISIBLE_ROW (sheet)+1;
- case GDK_Down:
- if (extend_selection)
- {
- if (state == GTK_STATE_NORMAL)
- {
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- gtk_sheet_click_cell (sheet, row, col, &veto);
- if (!veto) break;
- }
- if (sheet->selection_cell.row < yyy_row_count (sheet)- 1)
- {
- row = sheet->selection_cell.row + scroll;
- while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) row++;
- row = MIN (yyy_row_count (sheet)- 1, row);
- gtk_sheet_extend_selection (sheet, row, sheet->selection_cell.col);
- }
- return TRUE;
- }
- col = sheet->active_cell.col;
- row = sheet->active_cell.row;
- if (sheet->active_cell.row < yyy_row_count (sheet)- 1)
- {
- if (state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet)- 1;
- if (state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet);
- row = row + scroll;
- while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) row++;
- row = MIN (yyy_row_count (sheet)- 1, row);
- }
- gtk_sheet_click_cell (sheet, row, col, &veto);
- extend_selection = FALSE;
+ case GTK_SCROLL_STEP_UP:
+ new_cell.row--;
+ break;
+ case GTK_SCROLL_STEP_RIGHT:
+ new_cell.col++;
+ break;
+ case GTK_SCROLL_STEP_LEFT:
+ new_cell.col--;
break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+
+ g_signal_emit (sheet, sheet_signals[TRAVERSE], 0,
+ &sheet->active_cell,
+ &new_cell,
+ &forbidden);
+
+ if (forbidden)
+ return;
+
+
+ maximize_int (&new_cell.row, 0);
+ maximize_int (&new_cell.col, 0);
+
+ minimize_int (&new_cell.row,
+ psppire_axis_unit_count (sheet->vaxis) - 1);
+
+ minimize_int (&new_cell.col,
+ psppire_axis_unit_count (sheet->haxis) - 1);
+
+ change_active_cell (sheet, new_cell.row, new_cell.col);
+
+
+ if ( new_cell.col > max_fully_visible_column (sheet))
+ {
+ glong hpos =
+ psppire_axis_start_pixel (sheet->haxis,
+ new_cell.col + 1);
+ hpos -= sheet->hadjustment->page_size;
+
+ gtk_adjustment_set_value (sheet->hadjustment,
+ hpos);
+ }
+ else if ( new_cell.col < min_fully_visible_column (sheet))
+ {
+ glong hpos =
+ psppire_axis_start_pixel (sheet->haxis,
+ new_cell.col);
+
+ gtk_adjustment_set_value (sheet->hadjustment,
+ hpos);
+ }
+
+
+ if ( new_cell.row > max_fully_visible_row (sheet))
+ {
+ glong vpos =
+ psppire_axis_start_pixel (sheet->vaxis,
+ new_cell.row + 1);
+ vpos -= sheet->vadjustment->page_size;
+
+ gtk_adjustment_set_value (sheet->vadjustment,
+ vpos);
+ }
+ else if ( new_cell.row < min_fully_visible_row (sheet))
+ {
+ glong vpos =
+ psppire_axis_start_pixel (sheet->vaxis,
+ new_cell.row);
+
+ gtk_adjustment_set_value (sheet->vadjustment,
+ vpos);
+ }
+
+ gtk_widget_grab_focus (GTK_WIDGET (sheet->entry_widget));
+}
+
+
+static gboolean
+gtk_sheet_key_press (GtkWidget *widget,
+ GdkEventKey *key)
+{
+ GtkSheet *sheet = GTK_SHEET (widget);
+
+ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+
+ switch (key->keyval)
+ {
+ case GDK_Tab:
case GDK_Right:
- if (extend_selection)
- {
- if (state == GTK_STATE_NORMAL)
- {
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- gtk_sheet_click_cell (sheet, row, col, &veto);
- if (!veto) break;
- }
- if (sheet->selection_cell.col < xxx_column_count (sheet) - 1)
- {
- col = sheet->selection_cell.col + 1;
- while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1)
- col++;
- gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col);
- }
- return TRUE;
- }
- col = sheet->active_cell.col;
- row = sheet->active_cell.row;
- if (sheet->active_cell.col < xxx_column_count (sheet) - 1)
- {
- col ++;
- if (state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet)- 1;
- if (state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet);
- while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1) col++;
- if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0
- || force_move)
- {
- gtk_sheet_click_cell (sheet, row, col, &veto);
- }
- else
- return FALSE;
- }
- extend_selection = FALSE;
+ step_sheet (sheet, GTK_SCROLL_STEP_RIGHT);
break;
+ case GDK_ISO_Left_Tab:
case GDK_Left:
- if (extend_selection)
- {
- if (state == GTK_STATE_NORMAL)
- {
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
- gtk_sheet_click_cell (sheet, row, col, &veto);
- if (!veto) break;
- }
- if (sheet->selection_cell.col > 0)
- {
- col = sheet->selection_cell.col - 1;
- while (! xxx_column_is_visible (sheet, col) && col > 0) col--;
- gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col);
- }
- return TRUE;
- }
- col = sheet->active_cell.col - 1;
- row = sheet->active_cell.row;
- if (state == GTK_SHEET_ROW_SELECTED)
- col = MIN_VISIBLE_COLUMN (sheet)- 1;
- if (state == GTK_SHEET_COLUMN_SELECTED)
- row = MIN_VISIBLE_ROW (sheet);
- while (! xxx_column_is_visible (sheet, col) && col > 0) col--;
- col = MAX (0, col);
-
- if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0
- || force_move)
- {
- gtk_sheet_click_cell (sheet, row, col, &veto);
- }
- else
- return FALSE;
- extend_selection = FALSE;
+ step_sheet (sheet, GTK_SCROLL_STEP_LEFT);
+ break;
+ case GDK_Return:
+ case GDK_Down:
+ step_sheet (sheet, GTK_SCROLL_STEP_DOWN);
+ break;
+ case GDK_Up:
+ step_sheet (sheet, GTK_SCROLL_STEP_UP);
+ break;
+
+ case GDK_Page_Down:
+ page_vertical (sheet, GTK_SCROLL_PAGE_DOWN);
+ break;
+ case GDK_Page_Up:
+ page_vertical (sheet, GTK_SCROLL_PAGE_UP);
break;
+
case GDK_Home:
- row = 0;
- while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet) - 1) row++;
- gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto);
- extend_selection = FALSE;
+ gtk_adjustment_set_value (sheet->vadjustment,
+ sheet->vadjustment->lower);
+
+ change_active_cell (sheet, 0,
+ sheet->active_cell.col);
+
break;
+
case GDK_End:
- row = yyy_row_count (sheet) - 1;
- while (!yyy_row_is_visible (sheet, row) && row > 0) row--;
- gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto);
- extend_selection = FALSE;
+ gtk_adjustment_set_value (sheet->vadjustment,
+ sheet->vadjustment->upper -
+ sheet->vadjustment->page_size -
+ sheet->vadjustment->page_increment);
+
+ /*
+ change_active_cellx (sheet,
+ psppire_axis_unit_count (sheet->vaxis) - 1,
+ sheet->active_cell.col);
+ */
+ break;
+ case GDK_Delete:
+ gtk_sheet_real_cell_clear (sheet, sheet->active_cell.row, sheet->active_cell.col);
break;
default:
- if (in_selection)
- {
- GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
- if (extend_selection) return TRUE;
- }
- if (state == GTK_SHEET_ROW_SELECTED)
- sheet->active_cell.col = MIN_VISIBLE_COLUMN (sheet);
- if (state == GTK_SHEET_COLUMN_SELECTED)
- sheet->active_cell.row = MIN_VISIBLE_ROW (sheet);
return FALSE;
+ break;
}
- if (extend_selection) return TRUE;
-
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
- sheet->active_cell.col);
-
return TRUE;
}
static void
-gtk_sheet_size_request (GtkWidget * widget,
- GtkRequisition * requisition)
+gtk_sheet_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
{
GtkSheet *sheet;
- GList *children;
- GtkSheetChild *child;
- GtkRequisition child_requisition;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_SHEET (widget));
sheet = GTK_SHEET (widget);
- requisition->width = 3*DEFAULT_COLUMN_WIDTH;
- requisition->height = 3*DEFAULT_ROW_HEIGHT (widget);
+ requisition->width = 3 * DEFAULT_COLUMN_WIDTH;
+ requisition->height = 3 * DEFAULT_ROW_HEIGHT;
/* compute the size of the column title area */
if (sheet->column_titles_visible)
/* compute the size of the row title area */
if (sheet->row_titles_visible)
requisition->width += sheet->row_title_area.width;
-
- children = sheet->children;
- while (children)
- {
- child = children->data;
- children = children->next;
-
- gtk_widget_size_request (child->widget, &child_requisition);
- }
}
static void
-gtk_sheet_size_allocate (GtkWidget * widget,
- GtkAllocation * allocation)
+gtk_sheet_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
GtkSheet *sheet;
GtkAllocation sheet_allocation;
allocation->width - 2 * border_width,
allocation->height - 2 * border_width);
- /* use internal allocation structure for all the math
- * because it's easier than always subtracting the container
- * border width */
- sheet->internal_allocation.x = 0;
- sheet->internal_allocation.y = 0;
- sheet->internal_allocation.width = allocation->width - 2 * border_width;
- sheet->internal_allocation.height = allocation->height - 2 * border_width;
-
sheet_allocation.x = 0;
sheet_allocation.y = 0;
sheet_allocation.width = allocation->width - 2 * border_width;
sheet_allocation.height = allocation->height - 2 * border_width;
- sheet->sheet_window_width = sheet_allocation.width;
- sheet->sheet_window_height = sheet_allocation.height;
-
if (GTK_WIDGET_REALIZED (widget))
gdk_window_move_resize (sheet->sheet_window,
sheet_allocation.x,
/* position the window which holds the column title buttons */
sheet->column_title_area.x = 0;
sheet->column_title_area.y = 0;
+ sheet->column_title_area.width = sheet_allocation.width ;
+
+
+ /* position the window which holds the row title buttons */
+ sheet->row_title_area.x = 0;
+ sheet->row_title_area.y = 0;
+ sheet->row_title_area.height = sheet_allocation.height;
+
if (sheet->row_titles_visible)
- sheet->column_title_area.x = sheet->row_title_area.width;
- sheet->column_title_area.width = sheet_allocation.width -
- sheet->column_title_area.x;
+ sheet->column_title_area.x += sheet->row_title_area.width;
+
+ if (sheet->column_titles_visible)
+ sheet->row_title_area.y += sheet->column_title_area.height;
+
+
if (GTK_WIDGET_REALIZED (widget) && sheet->column_titles_visible)
gdk_window_move_resize (sheet->column_title_window,
sheet->column_title_area.x,
sheet->column_title_area.width,
sheet->column_title_area.height);
- sheet->sheet_window_width = sheet_allocation.width;
- sheet->sheet_window_height = sheet_allocation.height;
-
- /* column button allocation */
- size_allocate_column_title_buttons (sheet);
-
- /* position the window which holds the row title buttons */
- sheet->row_title_area.x = 0;
- sheet->row_title_area.y = 0;
- if (sheet->column_titles_visible)
- sheet->row_title_area.y = sheet->column_title_area.height;
- sheet->row_title_area.height = sheet_allocation.height -
- sheet->row_title_area.y;
if (GTK_WIDGET_REALIZED (widget) && sheet->row_titles_visible)
gdk_window_move_resize (sheet->row_title_window,
sheet->row_title_area.width,
sheet->row_title_area.height);
+ if (sheet->haxis)
+ {
+ gint width = sheet->column_title_area.width;
+
+ if ( sheet->row_titles_visible)
+ width -= sheet->row_title_area.width;
+
+ g_object_set (sheet->haxis,
+ "minimum-extent", width,
+ NULL);
+ }
+
+
+ if (sheet->vaxis)
+ {
+ gint height = sheet->row_title_area.height;
+
+ if ( sheet->column_titles_visible)
+ height -= sheet->column_title_area.height;
- /* row button allocation */
- size_allocate_row_title_buttons (sheet);
- size_allocate_column_title_buttons (sheet);
+ g_object_set (sheet->vaxis,
+ "minimum-extent", height,
+ NULL);
+ }
- /* re - scale backing pixmap */
- gtk_sheet_make_backing_pixmap (sheet, 0, 0);
- gtk_sheet_position_children (sheet);
/* set the scrollbars adjustments */
adjust_scrollbars (sheet);
}
static void
-size_allocate_column_title_buttons (GtkSheet * sheet)
+draw_column_title_buttons (GtkSheet *sheet)
{
- gint i;
gint x, width;
if (!sheet->column_titles_visible) return;
if (!GTK_WIDGET_REALIZED (sheet))
return;
- width = sheet->sheet_window_width;
+ gdk_drawable_get_size (sheet->sheet_window, &width, NULL);
x = 0;
if (sheet->row_titles_visible)
{
- width -= sheet->row_title_area.width;
x = sheet->row_title_area.width;
}
sheet->column_title_area.height);
}
-
- if (MAX_VISIBLE_COLUMN (sheet) == xxx_column_count (sheet) - 1)
+ if (max_visible_column (sheet) ==
+ psppire_axis_unit_count (sheet->haxis) - 1)
gdk_window_clear_area (sheet->column_title_window,
0, 0,
sheet->column_title_area.width,
size_allocate_global_button (sheet);
- for (i = MIN_VISIBLE_COLUMN (sheet); i <= MAX_VISIBLE_COLUMN (sheet); i++)
- gtk_sheet_column_title_button_draw (sheet, i);
+ draw_column_title_buttons_range (sheet, min_visible_column (sheet),
+ max_visible_column (sheet));
}
static void
-size_allocate_row_title_buttons (GtkSheet * sheet)
+draw_row_title_buttons (GtkSheet *sheet)
{
- gint i;
- gint y, height;
+ gint y = 0;
+ gint height;
if (!sheet->row_titles_visible) return;
if (!GTK_WIDGET_REALIZED (sheet))
return;
- height = sheet->sheet_window_height;
- y = 0;
+ gdk_drawable_get_size (sheet->sheet_window, NULL, &height);
if (sheet->column_titles_visible)
{
- height -= sheet->column_title_area.height;
y = sheet->column_title_area.height;
}
sheet->row_title_area.width,
sheet->row_title_area.height);
}
- if (MAX_VISIBLE_ROW (sheet) == yyy_row_count (sheet)- 1)
+
+ if (max_visible_row (sheet) == psppire_axis_unit_count (sheet->vaxis) - 1)
gdk_window_clear_area (sheet->row_title_window,
0, 0,
sheet->row_title_area.width,
size_allocate_global_button (sheet);
- for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++)
- {
- if ( i >= yyy_row_count (sheet))
- break;
- gtk_sheet_row_title_button_draw (sheet, i);
- }
+
+ draw_row_title_buttons_range (sheet, min_visible_row (sheet),
+ max_visible_row (sheet));
}
static void
gtk_sheet_size_allocate_entry (GtkSheet *sheet)
{
- GtkAllocation shentry_allocation;
+ GtkAllocation entry_alloc;
GtkSheetCellAttr attributes = { 0 };
GtkEntry *sheet_entry;
- GtkStyle *style = NULL, *previous_style = NULL;
- gint row, col;
- gint size, max_size, text_size, column_width;
- const gchar *text;
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return;
- sheet_entry = GTK_ENTRY (gtk_sheet_get_entry (sheet));
+ sheet_entry = gtk_sheet_get_entry (sheet);
if ( ! gtk_sheet_get_attributes (sheet, sheet->active_cell.row,
sheet->active_cell.col,
if ( GTK_WIDGET_REALIZED (sheet->entry_widget) )
{
- if (!GTK_WIDGET (sheet_entry)->style)
- gtk_widget_ensure_style (GTK_WIDGET (sheet_entry));
+ GtkStyle *style = GTK_WIDGET (sheet_entry)->style;
- previous_style = GTK_WIDGET (sheet_entry)->style;
-
- style = gtk_style_copy (previous_style);
style->bg[GTK_STATE_NORMAL] = attributes.background;
style->fg[GTK_STATE_NORMAL] = attributes.foreground;
style->text[GTK_STATE_NORMAL] = attributes.foreground;
style->bg[GTK_STATE_ACTIVE] = attributes.background;
style->fg[GTK_STATE_ACTIVE] = attributes.foreground;
style->text[GTK_STATE_ACTIVE] = attributes.foreground;
-
- pango_font_description_free (style->font_desc);
- g_assert (attributes.font_desc);
- style->font_desc = pango_font_description_copy (attributes.font_desc);
-
- GTK_WIDGET (sheet_entry)->style = style;
- gtk_widget_size_request (sheet->entry_widget, NULL);
- GTK_WIDGET (sheet_entry)->style = previous_style;
-
- if (style != previous_style)
- {
- if (!GTK_IS_ITEM_ENTRY (sheet->entry_widget))
- {
- style->bg[GTK_STATE_NORMAL] = previous_style->bg[GTK_STATE_NORMAL];
- style->fg[GTK_STATE_NORMAL] = previous_style->fg[GTK_STATE_NORMAL];
- style->bg[GTK_STATE_ACTIVE] = previous_style->bg[GTK_STATE_ACTIVE];
- style->fg[GTK_STATE_ACTIVE] = previous_style->fg[GTK_STATE_ACTIVE];
- }
- gtk_widget_set_style (GTK_WIDGET (sheet_entry), style);
- g_object_unref (style);
- }
}
- if (GTK_IS_ITEM_ENTRY (sheet_entry))
- max_size = GTK_ITEM_ENTRY (sheet_entry)->text_max_size;
- else
- max_size = 0;
-
- text_size = 0;
- text = gtk_entry_get_text (GTK_ENTRY (sheet_entry));
- if (text && strlen (text) > 0)
- text_size = STRING_WIDTH (GTK_WIDGET (sheet), attributes.font_desc, text);
-
- column_width = xxx_column_width (sheet, sheet->active_cell.col);
-
- size = MIN (text_size, max_size);
- size = MAX (size, column_width - 2 * CELLOFFSET);
-
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
-
- shentry_allocation.x = COLUMN_LEFT_XPIXEL (sheet, sheet->active_cell.col);
- shentry_allocation.y = ROW_TOP_YPIXEL (sheet, sheet->active_cell.row);
- shentry_allocation.width = column_width;
- shentry_allocation.height = yyy_row_height (sheet, sheet->active_cell.row);
-
- if (GTK_IS_ITEM_ENTRY (sheet->entry_widget))
- {
- shentry_allocation.height -= 2 * CELLOFFSET;
- shentry_allocation.y += CELLOFFSET;
- shentry_allocation.width = size;
-
- switch (GTK_ITEM_ENTRY (sheet_entry)->justification)
- {
- case GTK_JUSTIFY_CENTER:
- shentry_allocation.x += column_width / 2 - size / 2;
- break;
- case GTK_JUSTIFY_RIGHT:
- shentry_allocation.x += column_width - size - CELLOFFSET;
- break;
- case GTK_JUSTIFY_LEFT:
- case GTK_JUSTIFY_FILL:
- shentry_allocation.x += CELLOFFSET;
- break;
- }
- }
+ rectangle_from_cell (sheet, sheet->active_cell.row,
+ sheet->active_cell.col, &entry_alloc);
- if (!GTK_IS_ITEM_ENTRY (sheet->entry_widget))
- {
- shentry_allocation.x += 2;
- shentry_allocation.y += 2;
- shentry_allocation.width -= MIN (shentry_allocation.width, 3);
- shentry_allocation.height -= MIN (shentry_allocation.height, 3);
- }
+ entry_alloc.width -= BORDER_WIDTH ;
+ entry_alloc.height -= BORDER_WIDTH ;
+ entry_alloc.x += DIV_RND_UP (BORDER_WIDTH, 2);
+ entry_alloc.y += DIV_RND_UP (BORDER_WIDTH, 2);
- gtk_widget_size_allocate (sheet->entry_widget, &shentry_allocation);
- if (previous_style == style) g_object_unref (previous_style);
+ gtk_widget_set_size_request (sheet->entry_widget, entry_alloc.width,
+ entry_alloc.height);
+ gtk_widget_size_allocate (sheet->entry_widget, &entry_alloc);
}
+
+/* Copy the sheet's font to the entry widget */
static void
-gtk_sheet_entry_set_max_size (GtkSheet *sheet)
+set_entry_widget_font (GtkSheet *sheet)
{
- gint i;
- gint size = 0;
- gint sizel = 0, sizer = 0;
- gint row, col;
- GtkJustification justification;
- gchar *s = NULL;
-
- row = sheet->active_cell.row;
- col = sheet->active_cell.col;
-
- if ( ! GTK_IS_ITEM_ENTRY (sheet->entry_widget) )
- return;
-
- justification = GTK_ITEM_ENTRY (sheet->entry_widget)->justification;
+ GtkRcStyle *style = gtk_widget_get_modifier_style (sheet->entry_widget);
- switch (justification)
- {
- case GTK_JUSTIFY_FILL:
- case GTK_JUSTIFY_LEFT:
- for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++)
- {
- if ((s = gtk_sheet_cell_get_text (sheet, row, i)))
- {
- g_free (s);
- break;
- }
- size +=xxx_column_width (sheet, i);
- }
- size = MIN (size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL (sheet, col));
- break;
- case GTK_JUSTIFY_RIGHT:
- for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--)
- {
- if ((s = gtk_sheet_cell_get_text (sheet, row, i)))
- {
- g_free (s);
- break;
- }
- size +=xxx_column_width (sheet, i);
- }
- break;
- case GTK_JUSTIFY_CENTER:
- for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++)
- {
- sizer += xxx_column_width (sheet, i);
- }
- for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--)
- {
- if ((s = gtk_sheet_cell_get_text (sheet, row, i)))
- {
- g_free (s);
- break;
- }
- sizel +=xxx_column_width (sheet, i);
- }
- size = 2 * MIN (sizel, sizer);
- break;
- }
+ pango_font_description_free (style->font_desc);
+ style->font_desc = pango_font_description_copy (GTK_WIDGET (sheet)->style->font_desc);
- if (size != 0)
- size += xxx_column_width (sheet, col);
- GTK_ITEM_ENTRY (sheet->entry_widget)->text_max_size = size;
+ gtk_widget_modify_style (sheet->entry_widget, style);
}
+
static void
create_sheet_entry (GtkSheet *sheet)
{
gtk_widget_unparent (sheet->entry_widget);
}
- if (sheet->entry_type)
- {
- sheet->entry_container = g_object_new (sheet->entry_type, NULL);
- g_object_ref_sink (sheet->entry_container);
- sheet->entry_widget = gtk_sheet_get_entry (sheet);
+ sheet->entry_widget = g_object_new (sheet->entry_type, NULL);
+ g_object_ref_sink (sheet->entry_widget);
- if ( NULL == sheet->entry_widget)
- {
- g_warning ("Entry type is %s. It must be GtkEntry subclass, or a widget containing one. "
- "Using default", g_type_name (sheet->entry_type));
- g_object_unref (sheet->entry_container);
- sheet->entry_widget = sheet->entry_container = gtk_item_entry_new ();
- }
- else
- {
- sheet->entry_widget = sheet->entry_container ;
- }
- }
- else
+ gtk_widget_size_request (sheet->entry_widget, NULL);
+
+ if ( GTK_IS_ENTRY (sheet->entry_widget))
{
- sheet->entry_widget = sheet->entry_container = gtk_item_entry_new ();
- g_object_ref_sink (sheet->entry_container);
+ g_object_set (sheet->entry_widget,
+ "has-frame", FALSE,
+ NULL);
}
- gtk_widget_size_request (sheet->entry_widget, NULL);
-
if (GTK_WIDGET_REALIZED (sheet))
{
gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window);
G_CALLBACK (gtk_sheet_entry_key_press),
sheet);
+ sheet->entry_handler_id =
+ g_signal_connect (sheet->entry_widget,
+ "changed",
+ G_CALLBACK (gtk_sheet_entry_changed),
+ sheet);
+
+ set_entry_widget_font (sheet);
+
gtk_widget_show (sheet->entry_widget);
}
}
}
-GtkWidget *
+
+GtkEntry *
gtk_sheet_get_entry (GtkSheet *sheet)
{
- GtkWidget *parent;
- GtkWidget *entry = NULL;
- GtkTableChild *table_child;
- GtkBoxChild *box_child;
- GList *children = NULL;
+ GtkWidget *w = sheet->entry_widget;
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
g_return_val_if_fail (sheet->entry_widget != NULL, NULL);
- if (GTK_IS_ENTRY (sheet->entry_container))
- return (sheet->entry_container);
+ while (! GTK_IS_ENTRY (w))
+ {
+ GtkWidget *entry = NULL;
- parent = sheet->entry_container;
+ if (GTK_IS_CONTAINER (w))
+ {
+ gtk_container_forall (GTK_CONTAINER (w), find_entry, &entry);
- if (GTK_IS_TABLE (parent)) children = GTK_TABLE (parent)->children;
- if (GTK_IS_BOX (parent)) children = GTK_BOX (parent)->children;
+ if (NULL == entry)
+ break;
- if (GTK_IS_CONTAINER (parent))
- {
- gtk_container_forall (GTK_CONTAINER (parent), find_entry, &entry);
-
- if (GTK_IS_ENTRY (entry))
- return entry;
- }
-
- if (!children) return NULL;
-
- while (children)
- {
- if (GTK_IS_TABLE (parent))
- {
- table_child = children->data;
- entry = table_child->widget;
+ w = entry;
}
- if (GTK_IS_BOX (parent))
- {
- box_child = children->data;
- entry = box_child->widget;
- }
-
- if (GTK_IS_ENTRY (entry))
- break;
- children = children->next;
}
-
- if (!GTK_IS_ENTRY (entry)) return NULL;
-
- return (entry);
-
-}
-
-GtkWidget *
-gtk_sheet_get_entry_widget (GtkSheet *sheet)
-{
- g_return_val_if_fail (sheet != NULL, NULL);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
- g_return_val_if_fail (sheet->entry_widget != NULL, NULL);
-
- return (sheet->entry_widget);
+ return GTK_ENTRY (w);
}
static void
-gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window,
+draw_button (GtkSheet *sheet, GdkWindow *window,
GtkSheetButton *button, gboolean is_sensitive,
GdkRectangle allocation)
{
GtkShadowType shadow_type;
gint text_width = 0, text_height = 0;
- GtkSheetChild *child = NULL;
PangoAlignment align = PANGO_ALIGN_LEFT;
gboolean rtl ;
gint state = 0;
- gint len = 0;
- gchar *line = 0;
g_return_if_fail (sheet != NULL);
g_return_if_fail (button != NULL);
+
rtl = gtk_widget_get_direction (GTK_WIDGET (sheet)) == GTK_TEXT_DIR_RTL;
gdk_window_clear_area (window,
if (button->label_visible)
{
-
- text_height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))- 2 * CELLOFFSET;
+ text_height = DEFAULT_ROW_HEIGHT -
+ 2 * COLUMN_TITLES_HEIGHT;
gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->fg_gc[button->state],
&allocation);
- gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->white_gc, &allocation);
+ gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->white_gc,
+ &allocation);
allocation.y += 2 * sheet->button->style->ythickness;
-
- if (button->label && strlen (button->label)>0)
+ if (button->label && strlen (button->label) > 0)
{
- gchar *words = 0;
+ PangoRectangle rect;
+ gchar *line = button->label;
+
PangoLayout *layout = NULL;
- gint real_x = allocation.x, real_y = allocation.y;
+ gint real_x = allocation.x;
+ gint real_y = allocation.y;
- words = button->label;
- line = g_new (gchar, 1);
- line[0]='\0';
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), line);
+ pango_layout_get_extents (layout, NULL, &rect);
- while (words && *words != '\0')
+ text_width = PANGO_PIXELS (rect.width);
+ switch (button->justification)
{
- if (*words != '\n')
- {
- len = strlen (line);
- line = g_realloc (line, len + 2);
- line[len]=*words;
- line[len + 1]='\0';
- }
- if (*words == '\n' || * (words + 1) == '\0')
- {
- text_width = STRING_WIDTH (GTK_WIDGET (sheet), GTK_WIDGET (sheet)->style->font_desc, line);
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), line);
- switch (button->justification)
- {
- case GTK_JUSTIFY_LEFT:
- real_x = allocation.x + CELLOFFSET;
- align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
- break;
- case GTK_JUSTIFY_RIGHT:
- real_x = allocation.x + allocation.width - text_width - CELLOFFSET;
- align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
- break;
- case GTK_JUSTIFY_CENTER:
- default:
- real_x = allocation.x + (allocation.width - text_width)/2;
- align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
- pango_layout_set_justify (layout, TRUE);
- }
- pango_layout_set_alignment (layout, align);
- gtk_paint_layout (GTK_WIDGET (sheet)->style,
- window,
- state,
- FALSE,
- &allocation,
- GTK_WIDGET (sheet),
- "label",
- real_x, real_y,
- layout);
- g_object_unref (layout);
-
- real_y += text_height + 2;
-
- g_free (line);
- line = g_new (gchar, 1);
- line[0]='\0';
- }
- words++;
+ case GTK_JUSTIFY_LEFT:
+ real_x = allocation.x + COLUMN_TITLES_HEIGHT;
+ align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
+ break;
+ case GTK_JUSTIFY_RIGHT:
+ real_x = allocation.x + allocation.width - text_width - COLUMN_TITLES_HEIGHT;
+ align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
+ break;
+ case GTK_JUSTIFY_CENTER:
+ default:
+ real_x = allocation.x + (allocation.width - text_width)/2;
+ align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
+ pango_layout_set_justify (layout, TRUE);
}
- g_free (line);
+ pango_layout_set_alignment (layout, align);
+ gtk_paint_layout (GTK_WIDGET (sheet)->style,
+ window,
+ state,
+ FALSE,
+ &allocation,
+ GTK_WIDGET (sheet),
+ "label",
+ real_x, real_y,
+ layout);
+ g_object_unref (layout);
}
gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->fg_gc[button->state],
}
- if ((child = button->child) && (child->widget))
- {
- child->x = allocation.x;
- child->y = allocation.y;
-
- child->x += (allocation.width - child->widget->requisition.width) / 2;
- child->y += (allocation.height - child->widget->requisition.height) / 2;
- allocation.x = child->x;
- allocation.y = child->y;
- allocation.width = child->widget->requisition.width;
- allocation.height = child->widget->requisition.height;
-
- allocation.x = child->x;
- allocation.y = child->y;
-
- gtk_widget_set_state (child->widget, button->state);
-
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) &&
- GTK_WIDGET_MAPPED (child->widget))
- {
- gtk_widget_size_allocate (child->widget,
- &allocation);
- gtk_widget_queue_draw (child->widget);
- }
- }
-
gtk_sheet_button_free (button);
}
-/* COLUMN value of - 1 indicates that the area to the right of the rightmost
- button should be redrawn */
-static void
-gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column)
-{
- GdkWindow *window = NULL;
- GdkRectangle allocation;
-
- gboolean is_sensitive = FALSE;
-
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
-
- if (column >= 0 && ! xxx_column_is_visible (sheet, column)) return;
- if (column >= 0 && !sheet->column_titles_visible) return;
- if (column >= 0 && column < MIN_VISIBLE_COLUMN (sheet)) return;
- if (column >= 0 && column > MAX_VISIBLE_COLUMN (sheet)) return;
-
- window = sheet->column_title_window;
- allocation.y = 0;
- allocation.height = sheet->column_title_area.height;
-
- if ( column == -1 )
- {
- const gint cols = xxx_column_count (sheet) ;
- allocation.x = COLUMN_LEFT_XPIXEL (sheet, cols - 1)
- ;
- allocation.width = sheet->column_title_area.width
- + sheet->column_title_area.x
- - allocation.x;
-
- gdk_window_clear_area (window,
- allocation.x, allocation.y,
- allocation.width, allocation.height);
- }
- else
- {
- GtkSheetButton *button = xxx_column_button (sheet, column);
- allocation.x = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING;
- if (sheet->row_titles_visible)
- allocation.x -= sheet->row_title_area.width;
-
- allocation.width = xxx_column_width (sheet, column);
-
- is_sensitive = xxx_column_is_sensitive (sheet, column);
- gtk_sheet_button_draw (sheet, window, button,
- is_sensitive, allocation);
-
- /* FIXME: Not freeing this button is correct (sort of),
- because in PSPP the model always returns a static copy */
-
- /* gtk_sheet_button_free (button); */
-
- }
-}
-
+/* Draw the column title buttons FIRST through to LAST */
static void
-gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row)
+draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint last)
{
- GdkWindow *window = NULL;
- GdkRectangle allocation;
- GtkSheetButton *button = NULL;
- gboolean is_sensitive = FALSE;
-
-
+ GdkRectangle rect;
+ gint col;
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
- if (row >= 0 && !yyy_row_is_visible (sheet, row)) return;
- if (row >= 0 && !sheet->row_titles_visible) return;
- if (row >= 0 && row < MIN_VISIBLE_ROW (sheet)) return;
- if (row >= 0 && row > MAX_VISIBLE_ROW (sheet)) return;
-
-
- window = sheet->row_title_window;
- button = yyy_row_button (sheet, row);
- allocation.x = 0;
- allocation.y = ROW_TOP_YPIXEL (sheet, row) + CELL_SPACING;
- if (sheet->column_titles_visible)
- allocation.y -= sheet->column_title_area.height;
- allocation.width = sheet->row_title_area.width;
- allocation.height = yyy_row_height (sheet, row);
- is_sensitive = yyy_row_is_sensitive (sheet, row);
-
- gtk_sheet_button_draw (sheet, window, button, is_sensitive, allocation);
-}
-
-/* SCROLLBARS
- *
- * functions:
- * adjust_scrollbars
- * vadjustment_value_changed
- * hadjustment_value_changed */
-
-static void
-adjust_scrollbars (GtkSheet * sheet)
-{
- if (sheet->vadjustment)
- {
- sheet->vadjustment->page_size = sheet->sheet_window_height;
- sheet->vadjustment->page_increment = sheet->sheet_window_height / 2;
- sheet->vadjustment->step_increment = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet));
- sheet->vadjustment->lower = 0;
- sheet->vadjustment->upper = SHEET_HEIGHT (sheet) + 80;
- g_signal_emit_by_name (sheet->vadjustment, "changed");
-
- }
-
- if (sheet->hadjustment)
- {
- sheet->hadjustment->page_size = sheet->sheet_window_width;
- sheet->hadjustment->page_increment = sheet->sheet_window_width / 2;
- sheet->hadjustment->step_increment = DEFAULT_COLUMN_WIDTH;
- sheet->hadjustment->lower = 0;
- sheet->hadjustment->upper = SHEET_WIDTH (sheet)+ 80;
- g_signal_emit_by_name (sheet->hadjustment, "changed");
-
- }
-}
-
-static void
-vadjustment_value_changed (GtkAdjustment * adjustment,
- gpointer data)
-{
- GtkSheet *sheet;
- gint diff, value, old_value;
- gint row, new_row;
- gint y = 0;
-
- g_return_if_fail (adjustment != NULL);
- g_return_if_fail (data != NULL);
- g_return_if_fail (GTK_IS_SHEET (data));
-
- sheet = GTK_SHEET (data);
-
- if (GTK_SHEET_IS_FROZEN (sheet)) return;
-
- row = ROW_FROM_YPIXEL (sheet, CELL_SPACING);
-
- old_value = - sheet->voffset;
-
- new_row = g_sheet_row_pixel_to_row (sheet->row_geometry,
- adjustment->value);
-
- y = g_sheet_row_start_pixel (sheet->row_geometry, new_row);
-
- if (adjustment->value > sheet->old_vadjustment && sheet->old_vadjustment > 0. &&
- yyy_row_height (sheet, row) > sheet->vadjustment->step_increment)
- {
- /* This avoids embarrassing twitching */
- if (row == new_row && row != yyy_row_count (sheet) - 1 &&
- adjustment->value - sheet->old_vadjustment >=
- sheet->vadjustment->step_increment &&
- new_row + 1 != MIN_VISIBLE_ROW (sheet))
- {
- new_row +=1;
- y = y+yyy_row_height (sheet, row);
- }
- }
-
- /* Negative old_adjustment enforces the redraw, otherwise avoid
- spureous redraw */
- if (sheet->old_vadjustment >= 0. && row == new_row)
- {
- sheet->old_vadjustment = sheet->vadjustment->value;
- return;
- }
-
- sheet->old_vadjustment = sheet->vadjustment->value;
- adjustment->value = y;
-
-
- if (new_row == 0)
- {
- sheet->vadjustment->step_increment = yyy_row_height (sheet, 0);
- }
- else
- {
- sheet->vadjustment->step_increment =
- MIN (yyy_row_height (sheet, new_row), yyy_row_height (sheet, new_row - 1));
- }
-
- sheet->vadjustment->value = adjustment->value;
-
- value = adjustment->value;
-
- if (value >= - sheet->voffset)
- {
- /* scroll down */
- diff = value + sheet->voffset;
- }
- else
- {
- /* scroll up */
- diff = - sheet->voffset - value;
- }
-
- sheet->voffset = - value;
-
- if (GTK_WIDGET_REALIZED (sheet->entry_widget) &&
- sheet->state == GTK_SHEET_NORMAL &&
- sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 &&
- !gtk_sheet_cell_isvisible (sheet, sheet->active_cell.row,
- sheet->active_cell.col))
- {
- const gchar *text;
-
- text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)));
-
- if (!text || strlen (text) == 0)
- gtk_sheet_cell_clear (sheet,
- sheet->active_cell.row,
- sheet->active_cell.col);
- gtk_widget_unmap (sheet->entry_widget);
- }
-
- gtk_sheet_position_children (sheet);
-
- gtk_sheet_range_draw (sheet, NULL);
- size_allocate_row_title_buttons (sheet);
- size_allocate_global_button (sheet);
-}
-
-static void
-hadjustment_value_changed (GtkAdjustment * adjustment,
- gpointer data)
-{
- GtkSheet *sheet;
- gint i, diff, value, old_value;
- gint column, new_column;
- gint x = 0;
-
- g_return_if_fail (adjustment != NULL);
- g_return_if_fail (data != NULL);
- g_return_if_fail (GTK_IS_SHEET (data));
-
- sheet = GTK_SHEET (data);
-
- if (GTK_SHEET_IS_FROZEN (sheet)) return;
-
- column = COLUMN_FROM_XPIXEL (sheet, CELL_SPACING);
-
- old_value = - sheet->hoffset;
-
- for (i = 0; i < xxx_column_count (sheet); i++)
- {
- if (xxx_column_is_visible (sheet, i)) x += xxx_column_width (sheet, i);
- if (x > adjustment->value) break;
- }
- x -= xxx_column_width (sheet, i);
- new_column = i;
-
- if (adjustment->value > sheet->old_hadjustment && sheet->old_hadjustment > 0 &&
- xxx_column_width (sheet, i) > sheet->hadjustment->step_increment)
- {
- /* This avoids embarrassing twitching */
- if (column == new_column && column != xxx_column_count (sheet) - 1 &&
- adjustment->value - sheet->old_hadjustment >=
- sheet->hadjustment->step_increment &&
- new_column + 1 != MIN_VISIBLE_COLUMN (sheet))
- {
- new_column += 1;
- x += xxx_column_width (sheet, column);
- }
- }
-
- /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
- if (sheet->old_hadjustment >= 0. && new_column == column)
- {
- sheet->old_hadjustment = sheet->hadjustment->value;
- return;
- }
-
- sheet->old_hadjustment = sheet->hadjustment->value;
- adjustment->value = x;
-
- if (new_column == 0)
- {
- sheet->hadjustment->step_increment = xxx_column_width (sheet, 0);
- }
- else
- {
- sheet->hadjustment->step_increment =
- MIN (xxx_column_width (sheet, new_column), xxx_column_width (sheet, new_column - 1));
- }
-
-
- sheet->hadjustment->value = adjustment->value;
-
- value = adjustment->value;
-
- if (value >= - sheet->hoffset)
- {
- /* scroll right */
- diff = value + sheet->hoffset;
- }
- else
- {
- /* scroll left */
- diff = - sheet->hoffset - value;
- }
-
- sheet->hoffset = - value;
- if (GTK_WIDGET_REALIZED (sheet->entry_widget) &&
- sheet->state == GTK_SHEET_NORMAL &&
- sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 &&
- !gtk_sheet_cell_isvisible (sheet, sheet->active_cell.row,
- sheet->active_cell.col))
- {
- const gchar *text;
-
- text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)));
- if (!text || strlen (text) == 0)
- gtk_sheet_cell_clear (sheet,
- sheet->active_cell.row,
- sheet->active_cell.col);
-
- gtk_widget_unmap (sheet->entry_widget);
- }
-
- gtk_sheet_position_children (sheet);
-
- gtk_sheet_range_draw (sheet, NULL);
- size_allocate_column_title_buttons (sheet);
-}
-
-
-/* COLUMN RESIZING */
-static void
-draw_xor_vline (GtkSheet * sheet)
-{
- GtkWidget *widget;
-
- g_return_if_fail (sheet != NULL);
-
- widget = GTK_WIDGET (sheet);
-
- gdk_draw_line (widget->window, sheet->xor_gc,
- sheet->x_drag,
- sheet->column_title_area.height,
- sheet->x_drag,
- sheet->sheet_window_height + 1);
-}
-
-/* ROW RESIZING */
-static void
-draw_xor_hline (GtkSheet * sheet)
-{
- GtkWidget *widget;
-
- g_return_if_fail (sheet != NULL);
-
- widget = GTK_WIDGET (sheet);
-
- gdk_draw_line (widget->window, sheet->xor_gc,
- sheet->row_title_area.width,
- sheet->y_drag,
-
- sheet->sheet_window_width + 1,
- sheet->y_drag);
-}
-
-/* SELECTED RANGE */
-static void
-draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range)
-{
- gint i;
- GdkRectangle clip_area, area;
- GdkGCValues values;
-
- area.x = COLUMN_LEFT_XPIXEL (sheet, range.col0);
- area.y = ROW_TOP_YPIXEL (sheet, range.row0);
- area.width = COLUMN_LEFT_XPIXEL (sheet, range.coli)- area.x+
- xxx_column_width (sheet, range.coli);
- area.height = ROW_TOP_YPIXEL (sheet, range.rowi)- area.y+
- yyy_row_height (sheet, range.rowi);
-
- clip_area.x = sheet->row_title_area.width;
- clip_area.y = sheet->column_title_area.height;
- clip_area.width = sheet->sheet_window_width;
- clip_area.height = sheet->sheet_window_height;
-
- if (!sheet->row_titles_visible) clip_area.x = 0;
- if (!sheet->column_titles_visible) clip_area.y = 0;
-
- if (area.x < 0)
- {
- area.width = area.width + area.x;
- area.x = 0;
- }
- if (area.width > clip_area.width) area.width = clip_area.width + 10;
- if (area.y < 0)
- {
- area.height = area.height + area.y;
- area.y = 0;
- }
- if (area.height > clip_area.height) area.height = clip_area.height + 10;
-
- clip_area.x--;
- clip_area.y--;
- clip_area.width += 3;
- clip_area.height += 3;
-
- gdk_gc_get_values (sheet->xor_gc, &values);
-
- gdk_gc_set_clip_rectangle (sheet->xor_gc, &clip_area);
-
- for (i = -1; i <= 1; ++i)
- gdk_draw_rectangle (sheet->sheet_window,
- sheet->xor_gc,
- FALSE,
- area.x + i, area.y + i,
- area.width - 2 * i, area.height - 2 * i);
-
-
- gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL);
-
- gdk_gc_set_foreground (sheet->xor_gc, &values.foreground);
-
-}
-
-
-/* this function returns the new width of the column being resized given
- * the column and x position of the cursor; the x cursor position is passed
- * in as a pointer and automaticaly corrected if it's beyond min / max limits */
-static guint
-new_column_width (GtkSheet * sheet,
- gint column,
- gint * x)
-{
- gint cx, width;
- guint min_width;
-
- cx = *x;
-
- min_width = sheet->column_requisition;
-
- /* you can't shrink a column to less than its minimum width */
- if (cx < COLUMN_LEFT_XPIXEL (sheet, column) + min_width)
- {
- *x = cx = COLUMN_LEFT_XPIXEL (sheet, column) + min_width;
- }
-
- /* calculate new column width making sure it doesn't end up
- * less than the minimum width */
- width = cx - COLUMN_LEFT_XPIXEL (sheet, column);
- if (width < min_width)
- width = min_width;
-
- xxx_set_column_width (sheet, column, width);
- size_allocate_column_title_buttons (sheet);
-
- return width;
-}
-
-/* this function returns the new height of the row being resized given
- * the row and y position of the cursor; the y cursor position is passed
- * in as a pointer and automaticaly corrected if it's beyond min / max limits */
-static guint
-new_row_height (GtkSheet * sheet,
- gint row,
- gint * y)
-{
- gint cy, height;
- guint min_height;
-
- cy = *y;
- min_height = sheet->row_requisition;
-
- /* you can't shrink a row to less than its minimum height */
- if (cy < ROW_TOP_YPIXEL (sheet, row) + min_height)
-
- {
- *y = cy = ROW_TOP_YPIXEL (sheet, row) + min_height;
- }
-
- /* calculate new row height making sure it doesn't end up
- * less than the minimum height */
- height = (cy - ROW_TOP_YPIXEL (sheet, row));
- if (height < min_height)
- height = min_height;
-
- yyy_set_row_height (sheet, row, height);
- size_allocate_row_title_buttons (sheet);
-
- return height;
-}
+ if (!sheet->column_titles_visible) return;
-static void
-gtk_sheet_set_column_width (GtkSheet * sheet,
- gint column,
- guint width)
-{
- guint min_width;
+ g_return_if_fail (first >= min_visible_column (sheet));
+ g_return_if_fail (last <= max_visible_column (sheet));
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
+ rect.y = 0;
+ rect.height = sheet->column_title_area.height;
+ rect.x = psppire_axis_start_pixel (sheet->haxis, first) + CELL_SPACING;
+ rect.width = psppire_axis_start_pixel (sheet->haxis, last) + CELL_SPACING
+ + psppire_axis_unit_size (sheet->haxis, last);
- if (column < 0 || column >= xxx_column_count (sheet))
- return;
+ rect.x -= sheet->hadjustment->value;
- gtk_sheet_column_size_request (sheet, column, &min_width);
- if (width < min_width) return;
+ minimize_int (&rect.width, sheet->column_title_area.width);
+ maximize_int (&rect.x, 0);
- xxx_set_column_width (sheet, column, width);
+ gdk_window_begin_paint_rect (sheet->column_title_window, &rect);
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet))
+ for (col = first ; col <= last ; ++col)
{
- size_allocate_column_title_buttons (sheet);
- adjust_scrollbars (sheet);
- gtk_sheet_size_allocate_entry (sheet);
- gtk_sheet_range_draw (sheet, NULL);
- }
-
- g_signal_emit (sheet, sheet_signals[CHANGED], 0, -1, column);
-}
+ GdkRectangle allocation;
+ gboolean is_sensitive = FALSE;
+ GtkSheetButton *
+ button = g_sheet_model_get_column_button (sheet->model, col);
+ allocation.y = 0;
+ allocation.x = psppire_axis_start_pixel (sheet->haxis, col)
+ + CELL_SPACING;
+ allocation.x -= sheet->hadjustment->value;
+ allocation.height = sheet->column_title_area.height;
+ allocation.width = psppire_axis_unit_size (sheet->haxis, col);
+ is_sensitive = g_sheet_model_get_column_sensitivity (sheet->model, col);
-void
-gtk_sheet_set_row_height (GtkSheet * sheet,
- gint row,
- guint height)
-{
- guint min_height;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
-
- if (row < 0 || row >= yyy_row_count (sheet))
- return;
-
- gtk_sheet_row_size_request (sheet, row, &min_height);
- if (height < min_height) return;
-
- yyy_set_row_height (sheet, row, height);
-
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet))
- {
- size_allocate_row_title_buttons (sheet);
- adjust_scrollbars (sheet);
- gtk_sheet_size_allocate_entry (sheet);
- gtk_sheet_range_draw (sheet, NULL);
+ draw_button (sheet, sheet->column_title_window,
+ button, is_sensitive, allocation);
}
- g_signal_emit (sheet, sheet_signals[CHANGED], 0, row, - 1);
+ gdk_window_end_paint (sheet->column_title_window);
}
-gboolean
-gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col,
- GtkSheetCellAttr *attributes)
-{
- const GdkColor *fg, *bg;
- const GtkJustification *j ;
- const PangoFontDescription *font_desc ;
- const GtkSheetCellBorder *border ;
-
- g_return_val_if_fail (sheet != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
-
- if (row < 0 || col < 0) return FALSE;
-
- init_attributes (sheet, col, attributes);
-
- if ( !sheet->model)
- return FALSE;
-
- attributes->is_editable = g_sheet_model_is_editable (sheet->model, row, col);
- attributes->is_visible = g_sheet_model_is_visible (sheet->model, row, col);
-
- fg = g_sheet_model_get_foreground (sheet->model, row, col);
- if ( fg )
- attributes->foreground = *fg;
-
- bg = g_sheet_model_get_background (sheet->model, row, col);
- if ( bg )
- attributes->background = *bg;
-
- j = g_sheet_model_get_justification (sheet->model, row, col);
- if (j) attributes->justification = *j;
-
- font_desc = g_sheet_model_get_font_desc (sheet->model, row, col);
- if ( font_desc ) attributes->font_desc = font_desc;
- border = g_sheet_model_get_cell_border (sheet->model, row, col);
-
- if ( border ) attributes->border = *border;
-
- return TRUE;
-}
static void
-init_attributes (const GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes)
+draw_row_title_buttons_range (GtkSheet *sheet, gint first, gint last)
{
- /* DEFAULT VALUES */
- attributes->foreground = GTK_WIDGET (sheet)->style->black;
- attributes->background = sheet->bg_color;
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
- {
- GdkColormap *colormap;
- colormap = gdk_colormap_get_system ();
- attributes->background = sheet->bg_color;
- }
- attributes->justification = xxx_column_justification (sheet, col);
- attributes->border.width = 0;
- attributes->border.line_style = GDK_LINE_SOLID;
- attributes->border.cap_style = GDK_CAP_NOT_LAST;
- attributes->border.join_style = GDK_JOIN_MITER;
- attributes->border.mask = 0;
- attributes->border.color = GTK_WIDGET (sheet)->style->black;
- attributes->is_editable = TRUE;
- attributes->is_visible = TRUE;
- attributes->font_desc = GTK_WIDGET (sheet)->style->font_desc;
-}
-
-
-/********************************************************************
- * Container Functions:
- * gtk_sheet_add
- * gtk_sheet_put
- * gtk_sheet_attach
- * gtk_sheet_remove
- * gtk_sheet_move_child
- * gtk_sheet_position_child
- * gtk_sheet_position_children
- * gtk_sheet_realize_child
- * gtk_sheet_get_child_at
- ********************************************************************/
-
-GtkSheetChild *
-gtk_sheet_put (GtkSheet *sheet, GtkWidget *child, gint x, gint y)
-{
- GtkRequisition child_requisition;
- GtkSheetChild *child_info;
+ GdkRectangle rect;
+ gint row;
+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return;
- g_return_val_if_fail (sheet != NULL, NULL);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
- g_return_val_if_fail (child != NULL, NULL);
- g_return_val_if_fail (child->parent == NULL, NULL);
+ if (!sheet->row_titles_visible) return;
- child_info = g_new (GtkSheetChild, 1);
- child_info->widget = child;
- child_info->x = x;
- child_info->y = y;
- child_info->attached_to_cell = FALSE;
- child_info->floating = TRUE;
- child_info->xpadding = child_info->ypadding = 0;
- child_info->xexpand = child_info->yexpand = FALSE;
- child_info->xshrink = child_info->yshrink = FALSE;
- child_info->xfill = child_info->yfill = FALSE;
+ g_return_if_fail (first >= min_visible_row (sheet));
+ g_return_if_fail (last <= max_visible_row (sheet));
- sheet->children = g_list_append (sheet->children, child_info);
+ rect.x = 0;
+ rect.width = sheet->row_title_area.width;
+ rect.y = psppire_axis_start_pixel (sheet->vaxis, first) + CELL_SPACING;
+ rect.height = psppire_axis_start_pixel (sheet->vaxis, last) + CELL_SPACING
+ + psppire_axis_unit_size (sheet->vaxis, last);
- gtk_widget_set_parent (child, GTK_WIDGET (sheet));
+ rect.y -= sheet->vadjustment->value;
- gtk_widget_size_request (child, &child_requisition);
+ minimize_int (&rect.height, sheet->row_title_area.height);
+ maximize_int (&rect.y, 0);
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet)))
+ gdk_window_begin_paint_rect (sheet->row_title_window, &rect);
+ for (row = first; row <= last; ++row)
{
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) &&
- (!GTK_WIDGET_REALIZED (child) || GTK_WIDGET_NO_WINDOW (child)))
- gtk_sheet_realize_child (sheet, child_info);
+ GdkRectangle allocation;
- if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) &&
- !GTK_WIDGET_MAPPED (child))
- gtk_widget_map (child);
- }
+ gboolean is_sensitive = FALSE;
- gtk_sheet_position_child (sheet, child_info);
+ GtkSheetButton *button =
+ g_sheet_model_get_row_button (sheet->model, row);
+ allocation.x = 0;
+ allocation.y = psppire_axis_start_pixel (sheet->vaxis, row)
+ + CELL_SPACING;
+ allocation.y -= sheet->vadjustment->value;
- /* This will avoid drawing on the titles */
+ allocation.width = sheet->row_title_area.width;
+ allocation.height = psppire_axis_unit_size (sheet->vaxis, row);
+ is_sensitive = g_sheet_model_get_row_sensitivity (sheet->model, row);
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
- {
- if (sheet->row_titles_visible)
- gdk_window_show (sheet->row_title_window);
- if (sheet->column_titles_visible)
- gdk_window_show (sheet->column_title_window);
+ draw_button (sheet, sheet->row_title_window,
+ button, is_sensitive, allocation);
}
- return (child_info);
+ gdk_window_end_paint (sheet->row_title_window);
}
-void
-gtk_sheet_attach_floating (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col)
-{
- GdkRectangle area;
- GtkSheetChild *child;
-
- if (row < 0 || col < 0)
- {
- gtk_sheet_button_attach (sheet, widget, row, col);
- return;
- }
-
- gtk_sheet_get_cell_area (sheet, row, col, &area);
- child = gtk_sheet_put (sheet, widget, area.x, area.y);
- child->attached_to_cell = TRUE;
- child->row = row;
- child->col = col;
-}
-
-void
-gtk_sheet_attach_default (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col)
-{
- if (row < 0 || col < 0)
- {
- gtk_sheet_button_attach (sheet, widget, row, col);
- return;
- }
-
- gtk_sheet_attach (sheet, widget, row, col,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-}
+/* SCROLLBARS
+ *
+ * functions:
+ * adjust_scrollbars
+ * vadjustment_value_changed
+ * hadjustment_value_changed */
-void
-gtk_sheet_attach (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col,
- gint xoptions,
- gint yoptions,
- gint xpadding,
- gint ypadding)
-{
- GdkRectangle area;
- GtkSheetChild *child = NULL;
- if (row < 0 || col < 0)
- {
- gtk_sheet_button_attach (sheet, widget, row, col);
- return;
- }
+static void
+update_adjustment (GtkAdjustment *adj, PsppireAxis *axis, gint page_size)
+{
+ double position =
+ (adj->value + adj->page_size)
+ /
+ (adj->upper - adj->lower);
- child = g_new0 (GtkSheetChild, 1);
- child->attached_to_cell = TRUE;
- child->floating = FALSE;
- child->widget = widget;
- child->row = row;
- child->col = col;
- child->xpadding = xpadding;
- child->ypadding = ypadding;
- child->xexpand = (xoptions & GTK_EXPAND) != 0;
- child->yexpand = (yoptions & GTK_EXPAND) != 0;
- child->xshrink = (xoptions & GTK_SHRINK) != 0;
- child->yshrink = (yoptions & GTK_SHRINK) != 0;
- child->xfill = (xoptions & GTK_FILL) != 0;
- child->yfill = (yoptions & GTK_FILL) != 0;
-
- sheet->children = g_list_append (sheet->children, child);
-
- gtk_sheet_get_cell_area (sheet, row, col, &area);
-
- child->x = area.x + child->xpadding;
- child->y = area.y + child->ypadding;
-
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet)))
- {
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) &&
- (!GTK_WIDGET_REALIZED (widget) || GTK_WIDGET_NO_WINDOW (widget)))
- gtk_sheet_realize_child (sheet, child);
+ const glong last_item = psppire_axis_unit_count (axis) - 1;
- if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) &&
- !GTK_WIDGET_MAPPED (widget))
- gtk_widget_map (widget);
- }
+ if (isnan (position) || position < 0)
+ position = 0;
- gtk_sheet_position_child (sheet, child);
+ adj->upper =
+ psppire_axis_start_pixel (axis, last_item)
+ +
+ psppire_axis_unit_size (axis, last_item)
+ ;
- /* This will avoid drawing on the titles */
+ adj->lower = 0;
+ adj->page_size = page_size;
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
- {
- if (GTK_SHEET_ROW_TITLES_VISIBLE (sheet))
- gdk_window_show (sheet->row_title_window);
- if (GTK_SHEET_COL_TITLES_VISIBLE (sheet))
- gdk_window_show (sheet->column_title_window);
- }
+#if 0
+ adj->value = position * (adj->upper - adj->lower) - adj->page_size;
+
+ if ( adj->value < adj->lower)
+ adj->value = adj->lower;
+#endif
+ gtk_adjustment_changed (adj);
}
-void
-gtk_sheet_button_attach (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col)
+
+static void
+adjust_scrollbars (GtkSheet *sheet)
{
- GtkSheetButton *button = 0;
- GtkSheetChild *child;
- GtkRequisition button_requisition;
+ gint width, height;
+
+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ return;
+
+ gdk_drawable_get_size (sheet->sheet_window, &width, &height);
- if (row >= 0 && col >= 0) return;
- if (row < 0 && col < 0) return;
+ if ( sheet->row_titles_visible)
+ width -= sheet->row_title_area.width;
- child = g_new (GtkSheetChild, 1);
- child->widget = widget;
- child->x = 0;
- child->y = 0;
- child->attached_to_cell = TRUE;
- child->floating = FALSE;
- child->row = row;
- child->col = col;
- child->xpadding = child->ypadding = 0;
- child->xshrink = child->yshrink = FALSE;
- child->xfill = child->yfill = FALSE;
+ if (sheet->column_titles_visible)
+ height -= sheet->column_title_area.height;
+ if (sheet->vadjustment)
+ {
+ glong last_row = psppire_axis_unit_count (sheet->vaxis) - 1;
- sheet->children = g_list_append (sheet->children, child);
+ sheet->vadjustment->step_increment =
+ ROWS_PER_STEP *
+ psppire_axis_unit_size (sheet->vaxis, last_row);
- gtk_sheet_button_size_request (sheet, button, &button_requisition);
+ sheet->vadjustment->page_increment =
+ height -
+ sheet->column_title_area.height -
+ psppire_axis_unit_size (sheet->vaxis, last_row);
+ update_adjustment (sheet->vadjustment, sheet->vaxis, height);
+ }
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet)))
+ if (sheet->hadjustment)
{
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) &&
- (!GTK_WIDGET_REALIZED (widget) || GTK_WIDGET_NO_WINDOW (widget)))
- gtk_sheet_realize_child (sheet, child);
+ gint last_col = psppire_axis_unit_count (sheet->haxis) - 1;
+ sheet->hadjustment->step_increment = 1;
- if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) &&
- !GTK_WIDGET_MAPPED (widget))
- gtk_widget_map (widget);
- }
+ sheet->hadjustment->page_increment = width;
- if (row == -1) size_allocate_column_title_buttons (sheet);
- if (col == -1) size_allocate_row_title_buttons (sheet);
+ sheet->hadjustment->upper =
+ psppire_axis_start_pixel (sheet->haxis, last_col)
+ +
+ psppire_axis_unit_size (sheet->haxis, last_col)
+ ;
+ update_adjustment (sheet->hadjustment, sheet->haxis, width);
+ }
}
static void
-label_size_request (GtkSheet *sheet, gchar *label, GtkRequisition *req)
+vadjustment_value_changed (GtkAdjustment *adjustment,
+ gpointer data)
{
- gchar *words;
- gchar word[1000];
- gint n = 0;
- gint row_height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)) - 2 * CELLOFFSET + 2;
+ GdkRegion *region;
+ GtkSheet *sheet = GTK_SHEET (data);
- req->height = 0;
- req->width = 0;
- words = label;
+ g_return_if_fail (adjustment != NULL);
- while (words && *words != '\0')
- {
- if (*words == '\n' || * (words + 1) == '\0')
- {
- req->height += row_height;
+ if ( ! GTK_WIDGET_REALIZED (sheet)) return;
- word[n] = '\0';
- req->width = MAX (req->width, STRING_WIDTH (GTK_WIDGET (sheet), GTK_WIDGET (sheet)->style->font_desc, word));
- n = 0;
- }
- else
- {
- word[n++] = *words;
- }
- words++;
- }
- if (n > 0) req->height -= 2;
-}
+ gtk_widget_hide (sheet->entry_widget);
-static void
-gtk_sheet_button_size_request (GtkSheet *sheet,
- const GtkSheetButton *button,
- GtkRequisition *button_requisition)
-{
- GtkRequisition requisition;
- GtkRequisition label_requisition;
+ region =
+ gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window));
- if (gtk_sheet_autoresize (sheet) && button->label && strlen (button->label) > 0)
- {
- label_size_request (sheet, button->label, &label_requisition);
- label_requisition.width += 2 * CELLOFFSET;
- label_requisition.height += 2 * CELLOFFSET;
- }
- else
- {
- label_requisition.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet));
- label_requisition.width = COLUMN_MIN_WIDTH;
- }
+ gdk_window_begin_paint_region (sheet->sheet_window, region);
- if (button->child)
- {
- gtk_widget_size_request (button->child->widget, &requisition);
- requisition.width += 2 * button->child->xpadding;
- requisition.height += 2 * button->child->ypadding;
- requisition.width += 2 * sheet->button->style->xthickness;
- requisition.height += 2 * sheet->button->style->ythickness;
- }
- else
- {
- requisition.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet));
- requisition.width = COLUMN_MIN_WIDTH;
- }
- *button_requisition = requisition;
- button_requisition->width = MAX (requisition.width, label_requisition.width);
- button_requisition->height = MAX (requisition.height, label_requisition.height);
+ gtk_sheet_range_draw (sheet, NULL);
+ draw_row_title_buttons (sheet);
+ // size_allocate_global_button (sheet);
+ gtk_sheet_draw_active_cell (sheet);
+ gdk_window_end_paint (sheet->sheet_window);
}
+
static void
-gtk_sheet_row_size_request (GtkSheet *sheet,
- gint row,
- guint *requisition)
+hadjustment_value_changed (GtkAdjustment *adjustment,
+ gpointer data)
{
- GtkRequisition button_requisition;
- GList *children;
-
- gtk_sheet_button_size_request (sheet,
- yyy_row_button (sheet, row),
- &button_requisition);
+ GdkRegion *region;
+ GtkSheet *sheet = GTK_SHEET (data);
- *requisition = button_requisition.height;
+ g_return_if_fail (adjustment != NULL);
- children = sheet->children;
- while (children)
- {
- GtkSheetChild *child = (GtkSheetChild *)children->data;
- GtkRequisition child_requisition;
+ if ( ! GTK_WIDGET_REALIZED (sheet)) return;
- if (child->attached_to_cell && child->row == row && child->col != -1 && !child->floating && !child->yshrink)
- {
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
+ gtk_widget_hide (sheet->entry_widget);
- if (child_requisition.height + 2 * child->ypadding > *requisition)
- *requisition = child_requisition.height + 2 * child->ypadding;
- }
- children = children->next;
- }
- sheet->row_requisition = * requisition;
-}
+ region =
+ gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window));
-static void
-gtk_sheet_column_size_request (GtkSheet *sheet,
- gint col,
- guint *requisition)
-{
- GtkRequisition button_requisition;
- GList *children;
- GtkSheetButton *button = xxx_column_button (sheet, col);
+ gdk_window_begin_paint_region (sheet->sheet_window, region);
- gtk_sheet_button_size_request (sheet,
- button,
- &button_requisition);
+ gtk_sheet_range_draw (sheet, NULL);
+ draw_column_title_buttons (sheet);
+ // size_allocate_global_button (sheet);
- gtk_sheet_button_free (button);
+ gtk_sheet_draw_active_cell (sheet);
- *requisition = button_requisition.width;
+ gdk_window_end_paint (sheet->sheet_window);
+}
- children = sheet->children;
- while (children)
- {
- GtkSheetChild *child = (GtkSheetChild *)children->data;
- GtkRequisition child_requisition;
- if (child->attached_to_cell && child->col == col && child->row != -1 && !child->floating && !child->xshrink)
- {
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
+/* COLUMN RESIZING */
+static void
+draw_xor_vline (GtkSheet *sheet)
+{
+ gint height;
+ gint xpos = sheet->x_drag;
+ gdk_drawable_get_size (sheet->sheet_window,
+ NULL, &height);
- if (child_requisition.width + 2 * child->xpadding > *requisition)
- *requisition = child_requisition.width + 2 * child->xpadding;
- }
- children = children->next;
- }
+ if (sheet->row_titles_visible)
+ xpos += sheet->row_title_area.width;
- sheet->column_requisition = *requisition;
+ gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc,
+ xpos,
+ sheet->column_title_area.height,
+ xpos,
+ height + CELL_SPACING);
}
-void
-gtk_sheet_move_child (GtkSheet *sheet, GtkWidget *widget, gint x, gint y)
-{
- GtkSheetChild *child;
- GList *children;
-
- g_return_if_fail (sheet != NULL);
- g_return_if_fail (GTK_IS_SHEET (sheet));
+/* ROW RESIZING */
+static void
+draw_xor_hline (GtkSheet *sheet)
- children = sheet->children;
- while (children)
- {
- child = children->data;
+{
+ gint width;
+ gint ypos = sheet->y_drag;
- if (child->widget == widget)
- {
- child->x = x;
- child->y = y;
- child->row = ROW_FROM_YPIXEL (sheet, y);
- child->col = COLUMN_FROM_XPIXEL (sheet, x);
- gtk_sheet_position_child (sheet, child);
- return;
- }
+ gdk_drawable_get_size (sheet->sheet_window,
+ &width, NULL);
- children = children->next;
- }
- g_warning ("Widget must be a GtkSheet child");
+ if (sheet->column_titles_visible)
+ ypos += sheet->column_title_area.height;
+ gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc,
+ sheet->row_title_area.width,
+ ypos,
+ width + CELL_SPACING,
+ ypos);
}
+/* SELECTED RANGE */
static void
-gtk_sheet_position_child (GtkSheet *sheet, GtkSheetChild *child)
+draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range)
{
- GtkRequisition child_requisition;
- GtkAllocation child_allocation;
- gint xoffset = 0;
- gint yoffset = 0;
- gint x = 0, y = 0;
- GdkRectangle area;
-
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
-
- if (sheet->column_titles_visible)
- yoffset = sheet->column_title_area.height;
+ gint i = 0;
+ GdkRectangle clip_area, area;
+ GdkGCValues values;
- if (sheet->row_titles_visible)
- xoffset = sheet->row_title_area.width;
+ area.x = psppire_axis_start_pixel (sheet->haxis, range.col0);
+ area.y = psppire_axis_start_pixel (sheet->vaxis, range.row0);
+ area.width = psppire_axis_start_pixel (sheet->haxis, range.coli)- area.x+
+ psppire_axis_unit_size (sheet->haxis, range.coli);
+ area.height = psppire_axis_start_pixel (sheet->vaxis, range.rowi)- area.y +
+ psppire_axis_unit_size (sheet->vaxis, range.rowi);
- if (child->attached_to_cell)
- {
- gtk_sheet_get_cell_area (sheet, child->row, child->col, &area);
- child->x = area.x + child->xpadding;
- child->y = area.y + child->ypadding;
+ clip_area.x = sheet->row_title_area.width;
+ clip_area.y = sheet->column_title_area.height;
- if (!child->floating)
- {
- if (child_requisition.width + 2 * child->xpadding <= xxx_column_width (sheet, child->col))
- {
- if (child->xfill)
- {
- child_requisition.width = child_allocation.width = xxx_column_width (sheet, child->col) - 2 * child->xpadding;
- }
- else
- {
- if (child->xexpand)
- {
- child->x = area.x + xxx_column_width (sheet, child->col) / 2 -
- child_requisition.width / 2;
- }
- child_allocation.width = child_requisition.width;
- }
- }
- else
- {
- if (!child->xshrink)
- {
- gtk_sheet_set_column_width (sheet, child->col, child_requisition.width + 2 * child->xpadding);
- }
- child_allocation.width = xxx_column_width (sheet, child->col) - 2 * child->xpadding;
- }
+ gdk_drawable_get_size (sheet->sheet_window,
+ &clip_area.width, &clip_area.height);
- if (child_requisition.height +
- 2 * child->ypadding <= yyy_row_height (sheet, child->row))
- {
- if (child->yfill)
- {
- child_requisition.height = child_allocation.height =
- yyy_row_height (sheet, child->row) - 2 * child->ypadding;
- }
- else
- {
- if (child->yexpand)
- {
- child->y = area.y + yyy_row_height (sheet, child->row) / 2
- - child_requisition.height / 2;
- }
- child_allocation.height = child_requisition.height;
- }
- }
- else
- {
- if (!child->yshrink)
- {
- gtk_sheet_set_row_height (sheet, child->row, child_requisition.height + 2 * child->ypadding);
- }
- child_allocation.height = yyy_row_height (sheet, child->row) -
- 2 * child->ypadding;
- }
- }
- else
- {
- child_allocation.width = child_requisition.width;
- child_allocation.height = child_requisition.height;
- }
+ if (!sheet->row_titles_visible) clip_area.x = 0;
+ if (!sheet->column_titles_visible) clip_area.y = 0;
- x = child_allocation.x = child->x + xoffset;
- y = child_allocation.y = child->y + yoffset;
+ if (area.x < 0)
+ {
+ area.width = area.width + area.x;
+ area.x = 0;
}
- else
+ if (area.width > clip_area.width) area.width = clip_area.width + 10;
+ if (area.y < 0)
{
- x = child_allocation.x = child->x + sheet->hoffset + xoffset;
- x = child_allocation.x = child->x + xoffset;
- y = child_allocation.y = child->y + sheet->voffset + yoffset;
- y = child_allocation.y = child->y + yoffset;
- child_allocation.width = child_requisition.width;
- child_allocation.height = child_requisition.height;
+ area.height = area.height + area.y;
+ area.y = 0;
}
+ if (area.height > clip_area.height) area.height = clip_area.height + 10;
- gtk_widget_size_allocate (child->widget, &child_allocation);
- gtk_widget_queue_draw (child->widget);
-}
+ clip_area.x--;
+ clip_area.y--;
+ clip_area.width += 3;
+ clip_area.height += 3;
-static void
-gtk_sheet_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- GtkSheet *sheet;
- GtkSheetChild *child;
- GList *children;
+ gdk_gc_get_values (sheet->xor_gc, &values);
- g_return_if_fail (GTK_IS_SHEET (container));
- g_return_if_fail (callback != NULL);
+ gdk_gc_set_clip_rectangle (sheet->xor_gc, &clip_area);
- sheet = GTK_SHEET (container);
- children = sheet->children;
- while (children)
- {
- child = children->data;
- children = children->next;
+ gdk_draw_rectangle (sheet->sheet_window,
+ sheet->xor_gc,
+ FALSE,
+ area.x + i, area.y + i,
+ area.width - 2 * i, area.height - 2 * i);
- (* callback) (child->widget, callback_data);
- }
- if (sheet->button && sheet->button->parent)
- (* callback) (sheet->button, callback_data);
+ gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL);
- if (sheet->entry_container && GTK_IS_CONTAINER (sheet->entry_container))
- (* callback) (sheet->entry_container, callback_data);
+ gdk_gc_set_foreground (sheet->xor_gc, &values.foreground);
}
static void
-gtk_sheet_position_children (GtkSheet *sheet)
+set_column_width (GtkSheet *sheet,
+ gint column,
+ gint width)
{
- GList *children;
- GtkSheetChild *child;
-
- children = sheet->children;
-
- while (children)
- {
- child = (GtkSheetChild *)children->data;
+ g_return_if_fail (sheet != NULL);
+ g_return_if_fail (GTK_IS_SHEET (sheet));
- if (child->col != -1 && child->row != -1)
- gtk_sheet_position_child (sheet, child);
+ if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis))
+ return;
- if (child->row == -1)
- {
- if (child->col < MIN_VISIBLE_COLUMN (sheet) ||
- child->col > MAX_VISIBLE_COLUMN (sheet))
- gtk_sheet_child_hide (child);
- else
- gtk_sheet_child_show (child);
- }
- if (child->col == -1)
- {
- if (child->row < MIN_VISIBLE_ROW (sheet) ||
- child->row > MAX_VISIBLE_ROW (sheet))
- gtk_sheet_child_hide (child);
- else
- gtk_sheet_child_show (child);
- }
+ psppire_axis_resize (sheet->haxis, column, width);
- children = children->next;
+ if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
+ {
+ draw_column_title_buttons (sheet);
+ adjust_scrollbars (sheet);
+ gtk_sheet_size_allocate_entry (sheet);
+ gtk_sheet_range_draw (sheet, NULL);
}
}
static void
-gtk_sheet_remove (GtkContainer *container, GtkWidget *widget)
+set_row_height (GtkSheet *sheet,
+ gint row,
+ gint height)
{
- GtkSheet *sheet;
- GList *children;
- GtkSheetChild *child = 0;
-
- g_return_if_fail (container != NULL);
- g_return_if_fail (GTK_IS_SHEET (container));
+ g_return_if_fail (sheet != NULL);
+ g_return_if_fail (GTK_IS_SHEET (sheet));
- sheet = GTK_SHEET (container);
+ if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis))
+ return;
- children = sheet->children;
+ psppire_axis_resize (sheet->vaxis, row, height);
- while (children)
+ if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) )
{
- child = (GtkSheetChild *)children->data;
+ draw_row_title_buttons (sheet);
+ adjust_scrollbars (sheet);
+ gtk_sheet_size_allocate_entry (sheet);
+ gtk_sheet_range_draw (sheet, NULL);
+ }
+}
- if (child->widget == widget) break;
+gboolean
+gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col,
+ GtkSheetCellAttr *attr)
+{
+ GdkColor *fg, *bg;
+ const GtkJustification *j ;
+ GdkColormap *colormap;
- children = children->next;
- }
+ g_return_val_if_fail (sheet != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE);
- if (children)
- {
- gtk_widget_unparent (widget);
- child->widget = NULL;
+ if (row < 0 || col < 0) return FALSE;
- sheet->children = g_list_remove_link (sheet->children, children);
- g_list_free_1 (children);
- g_free (child);
- }
+ attr->foreground = GTK_WIDGET (sheet)->style->black;
+ attr->background = sheet->color[BG_COLOR];
- gtk_widget_unparent (sheet->button);
-}
+ attr->border.width = 0;
+ attr->border.line_style = GDK_LINE_SOLID;
+ attr->border.cap_style = GDK_CAP_NOT_LAST;
+ attr->border.join_style = GDK_JOIN_MITER;
+ attr->border.mask = 0;
+ attr->border.color = GTK_WIDGET (sheet)->style->black;
-static void
-gtk_sheet_realize_child (GtkSheet *sheet, GtkSheetChild *child)
-{
- GtkWidget *widget;
+ attr->is_editable = g_sheet_model_is_editable (sheet->model, row, col);
- widget = GTK_WIDGET (sheet);
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (sheet));
+ fg = g_sheet_model_get_foreground (sheet->model, row, col);
+ if ( fg )
+ {
+ gdk_colormap_alloc_color (colormap, fg, TRUE, TRUE);
+ attr->foreground = *fg;
+ }
- if (GTK_WIDGET_REALIZED (widget))
+ bg = g_sheet_model_get_background (sheet->model, row, col);
+ if ( bg )
{
- if (child->row == -1)
- gtk_widget_set_parent_window (child->widget, sheet->column_title_window);
- else if (child->col == -1)
- gtk_widget_set_parent_window (child->widget, sheet->row_title_window);
- else
- gtk_widget_set_parent_window (child->widget, sheet->sheet_window);
+ gdk_colormap_alloc_color (colormap, bg, TRUE, TRUE);
+ attr->background = *bg;
}
- gtk_widget_set_parent (child->widget, widget);
-}
+ attr->justification =
+ g_sheet_model_get_column_justification (sheet->model, col);
+ j = g_sheet_model_get_justification (sheet->model, row, col);
+ if (j)
+ attr->justification = *j;
+ return TRUE;
+}
-GtkSheetChild *
-gtk_sheet_get_child_at (GtkSheet *sheet, gint row, gint col)
+static void
+gtk_sheet_button_size_request (GtkSheet *sheet,
+ const GtkSheetButton *button,
+ GtkRequisition *button_requisition)
{
- GList *children;
- GtkSheetChild *child = 0;
-
- g_return_val_if_fail (sheet != NULL, NULL);
- g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL);
-
- children = sheet->children;
+ GtkRequisition requisition;
+ GtkRequisition label_requisition;
- while (children)
- {
- child = (GtkSheetChild *)children->data;
+ label_requisition.height = DEFAULT_ROW_HEIGHT;
+ label_requisition.width = COLUMN_MIN_WIDTH;
- if (child->attached_to_cell)
- if (child->row == row && child->col == col) break;
+ requisition.height = DEFAULT_ROW_HEIGHT;
+ requisition.width = COLUMN_MIN_WIDTH;
- children = children->next;
- }
- if (children) return child;
+ *button_requisition = requisition;
+ button_requisition->width = MAX (requisition.width, label_requisition.width);
+ button_requisition->height = MAX (requisition.height, label_requisition.height);
- return NULL;
}
static void
-gtk_sheet_child_hide (GtkSheetChild *child)
+gtk_sheet_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
{
- g_return_if_fail (child != NULL);
- gtk_widget_hide (child->widget);
-}
+ GtkSheet *sheet = GTK_SHEET (container);
-static void
-gtk_sheet_child_show (GtkSheetChild *child)
-{
- g_return_if_fail (child != NULL);
+ g_return_if_fail (callback != NULL);
+
+ if (sheet->button && sheet->button->parent)
+ (* callback) (sheet->button, callback_data);
- gtk_widget_show (child->widget);
+ if (sheet->entry_widget && GTK_IS_CONTAINER (sheet->entry_widget))
+ (* callback) (sheet->entry_widget, callback_data);
}
+
GSheetModel *
gtk_sheet_get_model (const GtkSheet *sheet)
{
button->state = GTK_STATE_NORMAL;
button->label = NULL;
button->label_visible = TRUE;
- button->child = NULL;
button->justification = GTK_JUSTIFY_FILL;
return button;
g_free (button);
}
-
static void
append_cell_text (GString *string, const GtkSheet *sheet, gint r, gint c)
{
g_free (celltext);
}
+
static GString *
range_to_text (const GtkSheet *sheet)
{
gint r, c;
GString *string;
- if ( !gtk_sheet_range_isvisible (sheet, sheet->range))
+ if ( !gtk_sheet_range_isvisible (sheet, &sheet->range))
return NULL;
string = g_string_sized_new (80);
gint r, c;
GString *string;
- if ( !gtk_sheet_range_isvisible (sheet, sheet->range))
+ if ( !gtk_sheet_range_isvisible (sheet, &sheet->range))
return NULL;
string = g_string_sized_new (480);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (sheet),
GDK_SELECTION_PRIMARY);
- if (gtk_sheet_range_isvisible (sheet, sheet->range))
+ if (gtk_sheet_range_isvisible (sheet, &sheet->range))
{
if (!gtk_clipboard_set_with_owner (clipboard, targets,
G_N_ELEMENTS (targets),
gtk_clipboard_clear (clipboard);
}
}
-
#include "gtkextra-sheet.h"
#include "gsheetmodel.h"
-#include "gsheet-column-iface.h"
-#include "gsheet-row-iface.h"
+#include "psppire-axis.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-typedef enum
-{
- GTK_SHEET_FOREGROUND,
- GTK_SHEET_BACKGROUND,
- GTK_SHEET_FONT,
- GTK_SHEET_JUSTIFICATION,
- GTK_SHEET_BORDER,
- GTK_SHEET_BORDER_COLOR,
- GTK_SHEET_IS_EDITABLE,
- GTK_SHEET_IS_VISIBLE
-} GtkSheetAttrType;
+G_BEGIN_DECLS
/* sheet->state */
-
enum
{
GTK_SHEET_NORMAL,
#define GTK_TYPE_SHEET_RANGE (gtk_sheet_range_get_type ())
+#define GTK_TYPE_SHEET_CELL (gtk_sheet_cell_get_type ())
#define GTK_TYPE_SHEET (gtk_sheet_get_type ())
#define GTK_SHEET(obj) GTK_CHECK_CAST (obj, gtk_sheet_get_type (), GtkSheet)
#define GTK_SHEET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_sheet_get_type (), GtkSheetClass)
#define GTK_IS_SHEET(obj) GTK_CHECK_TYPE (obj, gtk_sheet_get_type ())
-/* Public flags, for compatibility */
-
-#define GTK_SHEET_ROW_FROZEN(sheet) !gtk_sheet_rows_resizable (sheet)
-#define GTK_SHEET_COLUMN_FROZEN(sheet) !gtk_sheet_columns_resizable (sheet)
-#define GTK_SHEET_AUTORESIZE(sheet) gtk_sheet_autoresize (sheet)
-#define GTK_SHEET_ROW_TITLES_VISIBLE(sheet) gtk_sheet_row_titles_visible (sheet)
-#define GTK_SHEET_COL_TITLES_VISIBLE(sheet) gtk_sheet_column_titles_visible (sheet)
-#define GTK_SHEET_AUTO_SCROLL(sheet) gtk_sheet_autoscroll (sheet)
-#define GTK_SHEET_JUSTIFY_ENTRY(sheet) gtk_sheet_justify_entry (sheet)
-
typedef struct _GtkSheetClass GtkSheetClass;
typedef struct _GtkSheetCellAttr GtkSheetCellAttr;
-typedef struct _GtkSheetCell GtkSheetCell;
+
typedef struct _GtkSheetHoverTitle GtkSheetHoverTitle;
struct _GtkSheetCellAttr
{
GtkJustification justification;
- const PangoFontDescription *font_desc;
GdkColor foreground;
GdkColor background;
GtkSheetCellBorder border;
gboolean is_editable;
- gboolean is_visible;
-};
-
-struct _GtkSheetCell
-{
- gint row;
- gint col;
};
struct _GtkSheetHoverTitle
gint row, column;
};
+enum
+ {
+ BG_COLOR,
+ GRID_COLOR,
+ n_COLORS
+ };
+
struct _GtkSheet
{
- GtkContainer container;
-
+ GtkBin parent;
gboolean dispose_has_run;
- GSheetColumn *column_geometry;
- GSheetRow *row_geometry;
+ PsppireAxis *haxis;
+ PsppireAxis *vaxis;
guint16 flags;
GSheetModel *model;
GtkSelectionMode selection_mode;
- gboolean autoresize;
- gboolean autoscroll;
- gboolean justify_entry;
- /* Background colors */
- GdkColor bg_color;
- GdkColor grid_color;
+ /* Component colors */
+ GdkColor color[n_COLORS];
gboolean show_grid;
- /* sheet children */
- GList *children;
-
- /* allocation rectangle after the container_border_width
- and the width of the shadow border */
- GdkRectangle internal_allocation;
-
- gint16 column_requisition;
- gint16 row_requisition;
-
- gboolean rows_resizable;
- gboolean columns_resizable;
-
/* active cell */
GtkSheetCell active_cell;
/* The GtkEntry used for editing the cells */
GtkWidget *entry_widget;
- /* The widget containing entry_widget, or
- entry_widget itself if no container */
- GtkWidget *entry_container;
-
/* The type of entry_widget */
GtkType entry_type;
+ /* Handler of the "changed" callback for the entry widget */
+ glong entry_handler_id;
+
/* expanding selection */
GtkSheetCell selection_cell;
/* selected range */
GtkSheetRange range;
- /*the scrolling window and it's height and width to
+ /* the scrolling window and its height and width to
* make things a little speedier */
GdkWindow *sheet_window;
- guint sheet_window_width;
- guint sheet_window_height;
-
- /* sheet backing pixmap */
- GdkPixmap *pixmap;
-
- /* offsets for scrolling */
- gint hoffset;
- gint voffset;
- gfloat old_hadjustment;
- gfloat old_vadjustment;
/* border shadow style */
GtkShadowType shadow_type;
GdkRectangle column_title_area;
GdkWindow *column_title_window;
gboolean column_titles_visible;
+ /* TRUE if the cursor is over the column title window */
+ gboolean column_title_under;
/* Row Titles */
GdkRectangle row_title_area;
GdkWindow *row_title_window;
gboolean row_titles_visible;
+ /* TRUE if the cursor is over the row title window */
+ gboolean row_title_under;
/*scrollbars*/
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
- gint freeze_count;
-
/* xor GC for the verticle drag line */
GdkGC *xor_gc;
struct _GtkSheetClass
{
- GtkContainerClass parent_class;
+ GtkBinClass parent_class;
void (*set_scroll_adjustments) (GtkSheet *sheet,
GtkAdjustment *hadjustment,
gint row, gint column,
gint *new_row, gint *new_column);
- gboolean (*deactivate) (GtkSheet *sheet,
- gint row, gint column);
-
gboolean (*activate) (GtkSheet *sheet,
gint row, gint column);
/* create a new sheet */
-GtkWidget * gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo,
- GSheetModel *model);
-
-
-
-
-/* create a new browser sheet. It cells can not be edited */
-GtkWidget *
-gtk_sheet_new_browser (guint rows, guint columns, const gchar *title);
-
-void
-gtk_sheet_construct_browser (GtkSheet *sheet,
- guint rows, guint columns, const gchar *title);
+GtkWidget * gtk_sheet_new (GSheetModel *model);
/* create a new sheet with custom entry */
GtkWidget *
-gtk_sheet_new_with_custom_entry (GSheetRow *vgeo,
- GSheetColumn *hgeo,
- GtkType entry_type);
-void
-gtk_sheet_construct_with_custom_entry (GtkSheet *sheet,
- GSheetRow *vgeo,
- GSheetColumn *hgeo,
- GtkType entry_type);
-/* change scroll adjustments */
-void
-gtk_sheet_set_hadjustment (GtkSheet *sheet,
- GtkAdjustment *adjustment);
-void
-gtk_sheet_set_vadjustment (GtkSheet *sheet,
- GtkAdjustment *adjustment);
-/* Change entry */
-void
-gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type);
-
-/* Returns sheet's entry widget */
-GtkWidget *
-gtk_sheet_get_entry (GtkSheet *sheet);
-GtkWidget *
-gtk_sheet_get_entry_widget (GtkSheet *sheet);
+gtk_sheet_new_with_custom_entry (GtkType entry_type);
-/* Returns sheet->state
- * Added by Steven Rostedt <steven.rostedt@lmco.com> */
-gint
-gtk_sheet_get_state (GtkSheet *sheet);
-
-/* Returns sheet's ranges
- * Added by Murray Cumming */
-guint
-gtk_sheet_get_columns_count (GtkSheet *sheet);
+/* Change entry */
+void gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type);
-guint
-gtk_sheet_get_rows_count (GtkSheet *sheet);
+GtkEntry *gtk_sheet_get_entry (GtkSheet *sheet);
-void
-gtk_sheet_get_visible_range (GtkSheet *sheet,
- GtkSheetRange *range);
-void
-gtk_sheet_get_selected_range (GtkSheet *sheet,
+void gtk_sheet_get_selected_range (GtkSheet *sheet,
GtkSheetRange *range);
-void
-gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode);
-
-void
-gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize);
-
-gboolean
-gtk_sheet_autoresize (GtkSheet *sheet);
-
-void
-gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll);
-
-gboolean
-gtk_sheet_autoscroll (GtkSheet *sheet);
-
-void
-gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify);
-
-gboolean
-gtk_sheet_justify_entry (GtkSheet *sheet);
-
-void
-gtk_sheet_set_locked (GtkSheet *sheet, gboolean lock);
-
-gboolean
-gtk_sheet_locked (const GtkSheet *sheet);
-
-/* set sheet title */
-void
-gtk_sheet_set_title (GtkSheet *sheet, const gchar *title);
-
-/* freeze all visual updates of the sheet.
- * Then thaw the sheet after you have made a number of changes.
- * The updates will occure in a more efficent way than if
- * you made them on a unfrozen sheet */
-void
-gtk_sheet_freeze (GtkSheet *sheet);
-void
-gtk_sheet_thaw (GtkSheet *sheet);
-/* Background colors */
-void
-gtk_sheet_set_background (GtkSheet *sheet,
- GdkColor *bg_color);
-void
-gtk_sheet_set_grid (GtkSheet *sheet,
- GdkColor *grid_color);
-void
-gtk_sheet_show_grid (GtkSheet *sheet,
+void gtk_sheet_show_grid (GtkSheet *sheet,
gboolean show);
-gboolean
-gtk_sheet_grid_visible (GtkSheet *sheet);
-
-/* set/get column title */
-void
-gtk_sheet_set_column_title (GtkSheet * sheet,
- gint column,
- const gchar * title);
-
-const gchar *
-gtk_sheet_get_column_title (GtkSheet * sheet,
- gint column);
-
-/* set/get row title */
-void
-gtk_sheet_set_row_title (GtkSheet * sheet,
- gint row,
- const gchar * title);
-const gchar *
-gtk_sheet_get_row_title (GtkSheet * sheet,
- gint row);
-
-
-/* set/get button label */
-void
-gtk_sheet_row_button_add_label (GtkSheet *sheet,
- gint row, const gchar *label);
-const gchar *
-gtk_sheet_row_button_get_label (GtkSheet *sheet,
- gint row);
-void
-gtk_sheet_row_button_justify (GtkSheet *sheet,
- gint row, GtkJustification justification);
+gboolean gtk_sheet_grid_visible (GtkSheet *sheet);
/* scroll the viewing area of the sheet to the given column
* location the row should appear on the screen, 0.0 being top or left,
* 1.0 being bottom or right; if row or column is negative then there
* is no change */
-void
-gtk_sheet_moveto (GtkSheet *sheet,
+void gtk_sheet_moveto (GtkSheet *sheet,
gint row,
gint column,
gfloat row_align,
gfloat col_align);
-void
-gtk_sheet_show_row_titles (GtkSheet *sheet);
-void
-gtk_sheet_hide_row_titles (GtkSheet *sheet);
-void
-gtk_sheet_show_column_titles (GtkSheet *sheet);
-void
-gtk_sheet_hide_column_titles (GtkSheet *sheet);
-
-gboolean
-gtk_sheet_row_titles_visible (GtkSheet *sheet);
-
-
-/* set row button sensitivity. If sensitivity is TRUE can be toggled,
- * otherwise it acts as a title */
-void
-gtk_sheet_row_set_sensitivity (GtkSheet *sheet,
- gint row, gboolean sensitive);
-
-/* set sensitivity for all row buttons */
-void
-gtk_sheet_rows_set_sensitivity (GtkSheet *sheet, gboolean sensitive);
-void
-gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable);
-gboolean
-gtk_sheet_rows_resizable (GtkSheet *sheet);
-
-/* set row visibility. The default value is TRUE. If FALSE, the
- * row is hidden */
-void
-gtk_sheet_row_set_visibility (GtkSheet *sheet,
- gint row, gboolean visible);
-void
-gtk_sheet_row_label_set_visibility (GtkSheet *sheet,
- gint row, gboolean visible);
-void
-gtk_sheet_rows_labels_set_visibility (GtkSheet *sheet, gboolean visible);
-
+void gtk_sheet_show_row_titles (GtkSheet *sheet);
+void gtk_sheet_hide_row_titles (GtkSheet *sheet);
+void gtk_sheet_show_column_titles (GtkSheet *sheet);
+void gtk_sheet_hide_column_titles (GtkSheet *sheet);
/* select the row. The range is then highlighted, and the bounds are stored
* in sheet->range */
-void
-gtk_sheet_select_row (GtkSheet * sheet,
- gint row);
+void gtk_sheet_select_row (GtkSheet * sheet, gint row);
/* select the column. The range is then highlighted, and the bounds are stored
* in sheet->range */
-void
-gtk_sheet_select_column (GtkSheet * sheet,
- gint column);
-
-/* get scrollbars adjustment */
-GtkAdjustment *
-gtk_sheet_get_vadjustment (GtkSheet * sheet);
-GtkAdjustment *
-gtk_sheet_get_hadjustment (GtkSheet * sheet);
+void gtk_sheet_select_column (GtkSheet * sheet, gint column);
/* highlight the selected range and store bounds in sheet->range */
-void gtk_sheet_select_range (GtkSheet *sheet,
- const GtkSheetRange *range);
+void gtk_sheet_select_range (GtkSheet *sheet, const GtkSheetRange *range);
+
+void gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range);
+
/* obvious */
void gtk_sheet_unselect_range (GtkSheet *sheet);
-/* set active cell where the entry will be displayed
- * returns FALSE if current cell can't be deactivated or
- * requested cell can't be activated */
-gboolean
-gtk_sheet_set_active_cell (GtkSheet *sheet,
- gint row, gint column);
+/* set active cell where the entry will be displayed */
+void gtk_sheet_set_active_cell (GtkSheet *sheet,
+ gint row, gint column);
/* Sets *ROW and *COLUMN to be the coordinates of the active cell.
ROW and/or COLUMN may be null if the caller is not interested in their
values */
-void
-gtk_sheet_get_active_cell (GtkSheet *sheet,
+void gtk_sheet_get_active_cell (GtkSheet *sheet,
gint *row, gint *column);
-/* set cell contents and allocate memory if needed */
-void
-gtk_sheet_set_cell (GtkSheet *sheet,
- gint row, gint col,
- GtkJustification justification,
- const gchar *text);
-void
-gtk_sheet_set_cell_text (GtkSheet *sheet,
- gint row, gint col,
- const gchar *text);
/* get cell contents */
-gchar *
-gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col);
-
-/* clear cell contents */
-void
-gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint col);
-
-/* clear range contents. If range==NULL the whole sheet will be cleared */
-void
-gtk_sheet_range_clear (GtkSheet *sheet,
- const GtkSheetRange *range);
-
-/* get cell state: GTK_STATE_NORMAL, GTK_STATE_SELECTED */
-GtkStateType
-gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col);
-
-/* get row and column correspondig to the given position in the screen */
-gboolean
-gtk_sheet_get_pixel_info (GtkSheet * sheet,
- gint x,
- gint y,
- gint * row,
- gint * column);
-
-/* get area of a given cell */
-gboolean
-gtk_sheet_get_cell_area (GtkSheet *sheet,
- gint row,
- gint column,
- GdkRectangle *area);
-
-/* set row height */
-void
-gtk_sheet_set_row_height (GtkSheet * sheet,
- gint row,
- guint height);
-
-
-/* delete nrows rows starting in row */
-void
-gtk_sheet_delete_rows (GtkSheet *sheet, guint row, guint nrows);
-
-/* append nrows row to the end of the sheet */
-void
-gtk_sheet_add_row (GtkSheet *sheet, guint nrows);
-
-/* insert nrows rows before the given row and pull right */
-void
-gtk_sheet_insert_rows (GtkSheet *sheet, guint row, guint nrows);
-
-/* set abckground color of the given range */
-void
-gtk_sheet_range_set_background (GtkSheet *sheet,
- const GtkSheetRange *range,
- const GdkColor *color);
-
-/* set foreground color (text color) of the given range */
-void
-gtk_sheet_range_set_foreground (GtkSheet *sheet,
- const GtkSheetRange *range,
- const GdkColor *color);
-
-/* set text justification (GTK_JUSTIFY_LEFT, RIGHT, CENTER) of the given range.
- * The default value is GTK_JUSTIFY_LEFT. If autoformat is on, the
- * default justification for numbers is GTK_JUSTIFY_RIGHT */
-void
-gtk_sheet_range_set_justification (GtkSheet *sheet,
- const GtkSheetRange *range,
- GtkJustification justification);
-void
-gtk_sheet_column_set_justification (GtkSheet *sheet,
- gint column,
- GtkJustification justification);
-/* set if cell contents can be edited or not in the given range:
- * accepted values are TRUE or FALSE. */
-void
-gtk_sheet_range_set_editable (GtkSheet *sheet,
- const GtkSheetRange *range,
- gint editable);
-
-/* set if cell contents are visible or not in the given range:
- * accepted values are TRUE or FALSE.*/
-void
-gtk_sheet_range_set_visible (GtkSheet *sheet,
- const GtkSheetRange *range,
- gboolean visible);
-
-/* set cell border style in the given range.
- * mask values are CELL_LEFT_BORDER, CELL_RIGHT_BORDER, CELL_TOP_BORDER,
- * CELL_BOTTOM_BORDER
- * width is the width of the border line in pixels
- * line_style is the line_style for the border line */
-void
-gtk_sheet_range_set_border (GtkSheet *sheet,
- const GtkSheetRange *range,
- gint mask,
- guint width,
- gint line_style);
-
-/* set border color for the given range */
-void
-gtk_sheet_range_set_border_color (GtkSheet *sheet,
- const GtkSheetRange *range,
- const GdkColor *color);
-
-/* set font for the given range */
-void
-gtk_sheet_range_set_font (GtkSheet *sheet,
- const GtkSheetRange *range,
- PangoFontDescription *font);
+gchar *gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col);
+
/* get cell attributes of the given cell */
/* TRUE means that the cell is currently allocated */
-gboolean
-gtk_sheet_get_attributes (const GtkSheet *sheet,
+gboolean gtk_sheet_get_attributes (const GtkSheet *sheet,
gint row, gint col,
GtkSheetCellAttr *attributes);
-
-GtkSheetChild *
-gtk_sheet_put (GtkSheet *sheet,
- GtkWidget *widget,
- gint x, gint y);
-void
-gtk_sheet_attach_floating (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col);
-void
-gtk_sheet_attach_default (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col);
-void
-gtk_sheet_attach (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col,
- gint xoptions,
- gint yoptions,
- gint xpadding,
- gint ypadding);
-
-
-void
-gtk_sheet_move_child (GtkSheet *sheet,
- GtkWidget *widget,
- gint x, gint y);
-
-GtkSheetChild *
-gtk_sheet_get_child_at (GtkSheet *sheet,
- gint row, gint col);
-
-void
-gtk_sheet_button_attach (GtkSheet *sheet,
- GtkWidget *widget,
- gint row, gint col);
-
-
-
-void gtk_sheet_set_model (GtkSheet *sheet,
+void gtk_sheet_set_model (GtkSheet *sheet,
GSheetModel *model);
GSheetModel * gtk_sheet_get_model (const GtkSheet *sheet);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* __GTK_SHEET_H__ */
--- /dev/null
+/*******************************************************************************
+**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+** 10 20 30 40 50 60 70 80
+**
+** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+
+** Copyright (C) 2005-2006 Mirco "MacSlow" Müller <macslow@bangang.de>
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** GtkXPaned is based on GtkPaned which was done by...
+**
+** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald"
+**
+** and later modified by...
+**
+** "the GTK+ Team and others 1997-2000"
+**
+*******************************************************************************/
+
+#include "gtkxpaned.h"
+#include <gtksheet/psppire-marshal.h>
+#include <gtk/gtkbindings.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkmain.h>
+
+enum WidgetProperties
+{
+ PROP_0,
+ PROP_X_POSITION,
+ PROP_Y_POSITION,
+ PROP_POSITION_SET,
+ PROP_MIN_X_POSITION,
+ PROP_MIN_Y_POSITION,
+ PROP_MAX_X_POSITION,
+ PROP_MAX_Y_POSITION
+};
+
+enum ChildProperties
+{
+ CHILD_PROP_0,
+ CHILD_PROP_RESIZE,
+ CHILD_PROP_SHRINK
+};
+
+enum WidgetSignals
+{
+ CYCLE_CHILD_FOCUS,
+ TOGGLE_HANDLE_FOCUS,
+ MOVE_HANDLE,
+ CYCLE_HANDLE_FOCUS,
+ ACCEPT_POSITION,
+ CANCEL_POSITION,
+ LAST_SIGNAL
+};
+
+static void gtk_xpaned_class_init (GtkXPanedClass* klass);
+
+static void gtk_xpaned_init (GtkXPaned* xpaned);
+
+static void gtk_xpaned_size_request (GtkWidget* widget,
+ GtkRequisition* requisition);
+
+static void gtk_xpaned_size_allocate (GtkWidget* widget,
+ GtkAllocation* allocation);
+
+static void gtk_xpaned_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void gtk_xpaned_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void gtk_xpaned_set_child_property (GtkContainer* container,
+ GtkWidget* child,
+ guint property_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void gtk_xpaned_get_child_property (GtkContainer* container,
+ GtkWidget* child,
+ guint property_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void gtk_xpaned_finalize (GObject* object);
+
+static void gtk_xpaned_realize (GtkWidget* widget);
+
+static void gtk_xpaned_unrealize (GtkWidget* widget);
+
+static void gtk_xpaned_map (GtkWidget* widget);
+
+static void gtk_xpaned_unmap (GtkWidget* widget);
+
+static gboolean gtk_xpaned_expose (GtkWidget* widget, GdkEventExpose* event);
+
+static gboolean gtk_xpaned_enter (GtkWidget* widget, GdkEventCrossing* event);
+
+static gboolean gtk_xpaned_leave (GtkWidget* widget, GdkEventCrossing* event);
+
+static gboolean gtk_xpaned_button_press (GtkWidget* widget,
+ GdkEventButton* event);
+
+static gboolean gtk_xpaned_button_release (GtkWidget* widget,
+ GdkEventButton* event);
+
+static gboolean gtk_xpaned_motion (GtkWidget* widget, GdkEventMotion* event);
+
+static gboolean gtk_xpaned_focus (GtkWidget* widget,
+ GtkDirectionType direction);
+
+static void gtk_xpaned_add (GtkContainer* container, GtkWidget* widget);
+
+static void gtk_xpaned_remove (GtkContainer* container, GtkWidget* widget);
+
+static void gtk_xpaned_forall (GtkContainer* container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+
+static void gtk_xpaned_set_focus_child (GtkContainer* container,
+ GtkWidget* child);
+
+static void gtk_xpaned_set_saved_focus (GtkXPaned* xpaned, GtkWidget* widget);
+
+static void gtk_xpaned_set_first_xpaned (GtkXPaned* xpaned,
+ GtkXPaned* first_xpaned);
+
+static void gtk_xpaned_set_last_top_left_child_focus (GtkXPaned* xpaned,
+ GtkWidget* widget);
+
+static void gtk_xpaned_set_last_top_right_child_focus (GtkXPaned* xpaned,
+ GtkWidget* widget);
+
+static void gtk_xpaned_set_last_bottom_left_child_focus (GtkXPaned* xpaned,
+ GtkWidget* widget);
+
+static void gtk_xpaned_set_last_bottom_right_child_focus (GtkXPaned* xpaned,
+ GtkWidget* widget);
+
+static gboolean gtk_xpaned_cycle_child_focus (GtkXPaned* xpaned,
+ gboolean reverse);
+
+static gboolean gtk_xpaned_cycle_handle_focus (GtkXPaned* xpaned,
+ gboolean reverse);
+
+static gboolean gtk_xpaned_move_handle (GtkXPaned* xpaned,
+ GtkScrollType scroll);
+
+static gboolean gtk_xpaned_accept_position (GtkXPaned* xpaned);
+
+static gboolean gtk_xpaned_cancel_position (GtkXPaned* xpaned);
+
+static gboolean gtk_xpaned_toggle_handle_focus (GtkXPaned* xpaned);
+
+static GType gtk_xpaned_child_type (GtkContainer* container);
+
+static GtkContainerClass* parent_class = NULL;
+
+struct _GtkXPanedPrivate
+{
+ GtkWidget *saved_focus;
+ GtkXPaned *first_xpaned;
+};
+
+GType gtk_xpaned_get_type (void)
+{
+ static GType xpaned_type = 0;
+
+ if (!xpaned_type)
+ {
+ static const GTypeInfo xpaned_info =
+ {
+ sizeof (GtkXPanedClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_xpaned_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkXPaned),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_xpaned_init
+ };
+
+ xpaned_type = g_type_register_static (GTK_TYPE_CONTAINER,
+ "GtkXPaned",
+ &xpaned_info,
+ 0);
+ }
+
+ return xpaned_type;
+}
+
+GtkWidget* gtk_xpaned_new (void)
+{
+ GtkXPaned* xpaned;
+
+ xpaned = g_object_new (GTK_TYPE_XPANED, NULL);
+
+ return GTK_WIDGET (xpaned);
+}
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void add_tab_bindings (GtkBindingSet* binding_set,
+ GdkModifierType modifiers)
+{
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_Tab,
+ modifiers,
+ "toggle_handle_focus",
+ 0);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Tab,
+ modifiers,
+ "toggle_handle_focus",
+ 0);
+}
+
+static void add_move_binding (GtkBindingSet* binding_set,
+ guint keyval,
+ GdkModifierType mask,
+ GtkScrollType scroll)
+{
+ gtk_binding_entry_add_signal (binding_set,
+ keyval,
+ mask,
+ "move_handle",
+ 1,
+ GTK_TYPE_SCROLL_TYPE,
+ scroll);
+}
+
+static void gtk_xpaned_class_init (GtkXPanedClass* class)
+{
+ GObjectClass* object_class;
+ GtkWidgetClass* widget_class;
+ GtkContainerClass* container_class;
+ GtkXPanedClass* xpaned_class;
+ GtkBindingSet* binding_set;
+
+ object_class = (GObjectClass *) class;
+ widget_class = (GtkWidgetClass *) class;
+ container_class = (GtkContainerClass *) class;
+ xpaned_class = (GtkXPanedClass *) class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->set_property = gtk_xpaned_set_property;
+ object_class->get_property = gtk_xpaned_get_property;
+ object_class->finalize = gtk_xpaned_finalize;
+
+ widget_class->realize = gtk_xpaned_realize;
+ widget_class->unrealize = gtk_xpaned_unrealize;
+ widget_class->map = gtk_xpaned_map;
+ widget_class->unmap = gtk_xpaned_unmap;
+ widget_class->expose_event = gtk_xpaned_expose;
+ widget_class->focus = gtk_xpaned_focus;
+ widget_class->enter_notify_event = gtk_xpaned_enter;
+ widget_class->leave_notify_event = gtk_xpaned_leave;
+ widget_class->button_press_event = gtk_xpaned_button_press;
+ widget_class->button_release_event = gtk_xpaned_button_release;
+ widget_class->motion_notify_event = gtk_xpaned_motion;
+ widget_class->size_request = gtk_xpaned_size_request;
+ widget_class->size_allocate = gtk_xpaned_size_allocate;
+
+ container_class->add = gtk_xpaned_add;
+ container_class->remove = gtk_xpaned_remove;
+ container_class->forall = gtk_xpaned_forall;
+ container_class->child_type = gtk_xpaned_child_type;
+ container_class->set_focus_child = gtk_xpaned_set_focus_child;
+ container_class->set_child_property = gtk_xpaned_set_child_property;
+ container_class->get_child_property = gtk_xpaned_get_child_property;
+
+ xpaned_class->cycle_child_focus = gtk_xpaned_cycle_child_focus;
+ xpaned_class->toggle_handle_focus = gtk_xpaned_toggle_handle_focus;
+ xpaned_class->move_handle = gtk_xpaned_move_handle;
+ xpaned_class->cycle_handle_focus = gtk_xpaned_cycle_handle_focus;
+ xpaned_class->accept_position = gtk_xpaned_accept_position;
+ xpaned_class->cancel_position = gtk_xpaned_cancel_position;
+
+ g_object_class_install_property (object_class,
+ PROP_X_POSITION,
+ g_param_spec_int ("x-position",
+ ("x-Position"),
+ ("x-Position of paned separator in pixels (0 means all the way to the left)"),
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_Y_POSITION,
+ g_param_spec_int ("y-position",
+ "y-Position",
+ "y-Position of paned separator in pixels (0 means all the way to the top)",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_POSITION_SET,
+ g_param_spec_boolean ("position-set",
+ "Position Set",
+ "TRUE if the Position property should be used",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("handle-size",
+ "Handle Size",
+ "Width of handle",
+ 0,
+ G_MAXINT,
+ 3,
+ G_PARAM_READABLE));
+ /**
+ * GtkXPaned:min-x-position:
+ *
+ * The smallest possible value for the x-position property. This property is derived from the
+ * size and shrinkability of the widget's children.
+ *
+ * Since: 2.4
+ */
+ g_object_class_install_property (object_class,
+ PROP_MIN_X_POSITION,
+ g_param_spec_int ("min-x-position",
+ "Minimal x-Position",
+ "Smallest possible value for the \"x-position\" property",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE));
+
+ /**
+ * GtkXPaned:min-y-position:
+ *
+ * The smallest possible value for the y-position property. This property is derived from the
+ * size and shrinkability of the widget's children.
+ *
+ * Since: 2.4
+ */
+ g_object_class_install_property (object_class,
+ PROP_MIN_Y_POSITION,
+ g_param_spec_int ("min-y-position",
+ "Minimal y-Position",
+ "Smallest possible value for the \"y-position\" property",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE));
+
+ /**
+ * GtkPaned:max-x-position:
+ *
+ * The largest possible value for the x-position property. This property is derived from the
+ * size and shrinkability of the widget's children.
+ *
+ * Since: 2.4
+ */
+ g_object_class_install_property (object_class,
+ PROP_MAX_X_POSITION,
+ g_param_spec_int ("max-x-position",
+ "Maximal x-Position",
+ "Largest possible value for the \"x-position\" property",
+ 0,
+ G_MAXINT,
+ G_MAXINT,
+ G_PARAM_READABLE));
+
+ /**
+ * GtkPaned:max-y-position:
+ *
+ * The largest possible value for the y-position property. This property is derived from the
+ * size and shrinkability of the widget's children.
+ *
+ * Since: 2.4
+ */
+ g_object_class_install_property (object_class,
+ PROP_MAX_Y_POSITION,
+ g_param_spec_int ("max-y-position",
+ "Maximal y-Position",
+ "Largest possible value for the \"y-position\" property",
+ 0,
+ G_MAXINT,
+ G_MAXINT,
+ G_PARAM_READABLE));
+
+ /**
+ * GtkPaned:resize:
+ *
+ * The "resize" child property determines whether the child expands and
+ * shrinks along with the paned widget.
+ *
+ * Since: 2.4
+ */
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_RESIZE,
+ g_param_spec_boolean ("resize",
+ "Resize",
+ "If TRUE, the child expands and shrinks along with the paned widget",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ /**
+ * GtkPaned:shrink:
+ *
+ * The "shrink" child property determines whether the child can be made
+ * smaller than its requisition.
+ *
+ * Since: 2.4
+ */
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_SHRINK,
+ g_param_spec_boolean ("shrink",
+ "Shrink",
+ "If TRUE, the child can be made smaller than its requisition",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ signals [CYCLE_CHILD_FOCUS] = g_signal_new ("cycle-child-focus",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, cycle_child_focus),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__BOOLEAN,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_BOOLEAN);
+
+ signals [TOGGLE_HANDLE_FOCUS] = g_signal_new ("toggle-handle-focus",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, toggle_handle_focus),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ signals[MOVE_HANDLE] = g_signal_new ("move-handle",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, move_handle),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__ENUM,
+ G_TYPE_BOOLEAN, 1,
+ GTK_TYPE_SCROLL_TYPE);
+
+ signals [CYCLE_HANDLE_FOCUS] = g_signal_new ("cycle-handle-focus",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, cycle_handle_focus),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__BOOLEAN,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_BOOLEAN);
+
+ signals [ACCEPT_POSITION] = g_signal_new ("accept-position",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, accept_position),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ signals [CANCEL_POSITION] = g_signal_new ("cancel-position",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkXPanedClass, cancel_position),
+ NULL, NULL,
+ psppire_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ binding_set = gtk_binding_set_by_class (class);
+
+ /* F6 and friends */
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_F6, 0,
+ "cycle-child-focus", 1,
+ G_TYPE_BOOLEAN, FALSE);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_F6, GDK_SHIFT_MASK,
+ "cycle-child-focus", 1,
+ G_TYPE_BOOLEAN, TRUE);
+
+ /* F8 and friends */
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_F8, 0,
+ "cycle-handle-focus", 1,
+ G_TYPE_BOOLEAN, FALSE);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_F8, GDK_SHIFT_MASK,
+ "cycle-handle-focus", 1,
+ G_TYPE_BOOLEAN, TRUE);
+
+ add_tab_bindings (binding_set, 0);
+ add_tab_bindings (binding_set, GDK_CONTROL_MASK);
+ add_tab_bindings (binding_set, GDK_SHIFT_MASK);
+ add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK);
+
+ /* accept and cancel positions */
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_Escape, 0,
+ "cancel-position", 0);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_Return, 0,
+ "accept-position", 0);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Enter, 0,
+ "accept-position", 0);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_space, 0,
+ "accept-position", 0);
+
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Space, 0,
+ "accept-position", 0);
+
+ /* move handle */
+ add_move_binding (binding_set, GDK_Left, 0, GTK_SCROLL_STEP_LEFT);
+ add_move_binding (binding_set, GDK_KP_Left, 0, GTK_SCROLL_STEP_LEFT);
+ add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_LEFT);
+ add_move_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_LEFT);
+
+ add_move_binding (binding_set, GDK_Right, 0, GTK_SCROLL_STEP_RIGHT);
+ add_move_binding (binding_set, GDK_Right, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_RIGHT);
+ add_move_binding (binding_set, GDK_KP_Right, 0, GTK_SCROLL_STEP_RIGHT);
+ add_move_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_RIGHT);
+
+ add_move_binding (binding_set, GDK_Up, 0, GTK_SCROLL_STEP_UP);
+ add_move_binding (binding_set, GDK_Up, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_UP);
+ add_move_binding (binding_set, GDK_KP_Up, 0, GTK_SCROLL_STEP_UP);
+ add_move_binding (binding_set, GDK_KP_Up, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_UP);
+ add_move_binding (binding_set, GDK_Page_Up, 0, GTK_SCROLL_PAGE_UP);
+ add_move_binding (binding_set, GDK_KP_Page_Up, 0, GTK_SCROLL_PAGE_UP);
+
+ add_move_binding (binding_set, GDK_Down, 0, GTK_SCROLL_STEP_DOWN);
+ add_move_binding (binding_set, GDK_Down, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_DOWN);
+ add_move_binding (binding_set, GDK_KP_Down, 0, GTK_SCROLL_STEP_DOWN);
+ add_move_binding (binding_set, GDK_KP_Down, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_DOWN);
+ add_move_binding (binding_set, GDK_Page_Down, 0, GTK_SCROLL_PAGE_RIGHT);
+ add_move_binding (binding_set, GDK_KP_Page_Down, 0, GTK_SCROLL_PAGE_RIGHT);
+
+ add_move_binding (binding_set, GDK_Home, 0, GTK_SCROLL_START);
+ add_move_binding (binding_set, GDK_KP_Home, 0, GTK_SCROLL_START);
+ add_move_binding (binding_set, GDK_End, 0, GTK_SCROLL_END);
+ add_move_binding (binding_set, GDK_KP_End, 0, GTK_SCROLL_END);
+}
+
+static GType gtk_xpaned_child_type (GtkContainer* container)
+{
+ if (!GTK_XPANED (container)->top_left_child ||
+ !GTK_XPANED (container)->top_right_child ||
+ !GTK_XPANED (container)->bottom_left_child ||
+ !GTK_XPANED (container)->bottom_right_child)
+ return GTK_TYPE_WIDGET;
+ else
+ return G_TYPE_NONE;
+}
+
+static void gtk_xpaned_init (GtkXPaned* xpaned)
+{
+ GTK_WIDGET_SET_FLAGS (xpaned, GTK_NO_WINDOW | GTK_CAN_FOCUS);
+
+ xpaned->top_left_child = NULL;
+ xpaned->top_right_child = NULL;
+ xpaned->bottom_left_child = NULL;
+ xpaned->bottom_right_child = NULL;
+ xpaned->handle_east = NULL;
+ xpaned->handle_west = NULL;
+ xpaned->handle_north = NULL;
+ xpaned->handle_south = NULL;
+ xpaned->handle_middle = NULL;
+ xpaned->xor_gc = NULL;
+ xpaned->cursor_type_east = GDK_SB_V_DOUBLE_ARROW;
+ xpaned->cursor_type_west = GDK_SB_V_DOUBLE_ARROW;
+ xpaned->cursor_type_north = GDK_SB_H_DOUBLE_ARROW;
+ xpaned->cursor_type_south = GDK_SB_H_DOUBLE_ARROW;
+ xpaned->cursor_type_middle = GDK_FLEUR;
+
+ xpaned->handle_pos_east.width = 5;
+ xpaned->handle_pos_east.height = 5;
+ xpaned->handle_pos_west.width = 5;
+ xpaned->handle_pos_west.height = 5;
+ xpaned->handle_pos_north.width = 5;
+ xpaned->handle_pos_north.height = 5;
+ xpaned->handle_pos_south.width = 5;
+ xpaned->handle_pos_south.height = 5;
+ xpaned->handle_pos_middle.width = 5;
+ xpaned->handle_pos_middle.height = 5;
+
+ xpaned->position_set = FALSE;
+ xpaned->last_allocation.width = -1;
+ xpaned->last_allocation.height = -1;
+ xpaned->in_drag_vert = FALSE;
+ xpaned->in_drag_horiz = FALSE;
+ xpaned->in_drag_vert_and_horiz = FALSE;
+
+ xpaned->maximized[GTK_XPANED_TOP_LEFT] = FALSE;
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] = FALSE;
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = FALSE;
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = FALSE;
+
+ xpaned->priv = g_new0 (GtkXPanedPrivate, 1);
+ xpaned->last_top_left_child_focus = NULL;
+ xpaned->last_top_right_child_focus = NULL;
+ xpaned->last_bottom_left_child_focus = NULL;
+ xpaned->last_bottom_right_child_focus = NULL;
+ xpaned->in_recursion = FALSE;
+ xpaned->handle_prelit = FALSE;
+ xpaned->original_position.x = -1;
+ xpaned->original_position.y = -1;
+ xpaned->unmaximized_position.x = -1;
+ xpaned->unmaximized_position.y = -1;
+
+ xpaned->handle_pos_east.x = -1;
+ xpaned->handle_pos_east.y = -1;
+ xpaned->handle_pos_west.x = -1;
+ xpaned->handle_pos_west.y = -1;
+ xpaned->handle_pos_north.x = -1;
+ xpaned->handle_pos_north.y = -1;
+ xpaned->handle_pos_south.x = -1;
+ xpaned->handle_pos_south.y = -1;
+ xpaned->handle_pos_middle.x = -1;
+ xpaned->handle_pos_middle.y = -1;
+
+ xpaned->drag_pos.x = -1;
+ xpaned->drag_pos.y = -1;
+}
+
+static void gtk_xpaned_size_request (GtkWidget* widget,
+ GtkRequisition* requisition)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+ GtkRequisition child_requisition;
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child))
+ {
+ gtk_widget_size_request (xpaned->top_left_child, &child_requisition);
+
+ requisition->width = child_requisition.width;
+ requisition->height = child_requisition.height;
+ }
+
+ if (xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child))
+ {
+ gtk_widget_size_request (xpaned->top_right_child, &child_requisition);
+
+ requisition->width += child_requisition.width;
+ requisition->height = MAX (requisition->height, child_requisition.height);
+ }
+
+ if (xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child))
+ {
+ gtk_widget_size_request (xpaned->bottom_left_child, &child_requisition);
+
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+ }
+
+ if (xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child))
+ {
+ gtk_widget_size_request (xpaned->bottom_right_child, &child_requisition);
+
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height = MAX (requisition->height, child_requisition.height);
+ }
+
+ /* add 2 times the set border-width to the GtkXPaneds requisition */
+ requisition->width += GTK_CONTAINER (xpaned)->border_width * 2;
+ requisition->height += GTK_CONTAINER (xpaned)->border_width * 2;
+
+ /* also add the handle "thickness" to GtkXPaneds width- and height-requisitions */
+ if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) &&
+ xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) &&
+ xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) &&
+ xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child))
+ {
+ gint handle_size;
+
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+ requisition->width += handle_size;
+ requisition->height += handle_size;
+ }
+}
+
+void
+gtk_xpaned_compute_position (GtkXPaned* xpaned,
+ const GtkAllocation* allocation,
+ GtkRequisition* top_left_child_req,
+ GtkRequisition* top_right_child_req,
+ GtkRequisition* bottom_left_child_req,
+ GtkRequisition* bottom_right_child_req);
+
+
+static void gtk_xpaned_size_allocate (GtkWidget* widget,
+ GtkAllocation* allocation)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+ gint border_width = GTK_CONTAINER (xpaned)->border_width;
+ GtkAllocation top_left_child_allocation;
+ GtkAllocation top_right_child_allocation;
+ GtkAllocation bottom_left_child_allocation;
+ GtkAllocation bottom_right_child_allocation;
+ GtkRequisition top_left_child_requisition;
+ GtkRequisition top_right_child_requisition;
+ GtkRequisition bottom_left_child_requisition;
+ GtkRequisition bottom_right_child_requisition;
+ gint handle_size;
+
+ /* determine size of handle(s) */
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+
+ widget->allocation = *allocation;
+
+ if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) &&
+ xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) &&
+ xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) &&
+ xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child))
+ {
+ /* what sizes do the children want to be at least at */
+ gtk_widget_get_child_requisition (xpaned->top_left_child,
+ &top_left_child_requisition);
+ gtk_widget_get_child_requisition (xpaned->top_right_child,
+ &top_right_child_requisition);
+ gtk_widget_get_child_requisition (xpaned->bottom_left_child,
+ &bottom_left_child_requisition);
+ gtk_widget_get_child_requisition (xpaned->bottom_right_child,
+ &bottom_right_child_requisition);
+
+ /* determine the total requisition-sum of all requisitions of borders,
+ * handles, children etc. */
+ gtk_xpaned_compute_position (xpaned,
+ allocation,
+ &top_left_child_requisition,
+ &top_right_child_requisition,
+ &bottom_left_child_requisition,
+ &bottom_right_child_requisition);
+
+ /* calculate the current positions and sizes of the handles */
+ xpaned->handle_pos_east.x = widget->allocation.x + border_width + xpaned->top_left_child_size.width + handle_size;
+ xpaned->handle_pos_east.y = widget->allocation.y + border_width + xpaned->top_left_child_size.height;
+ xpaned->handle_pos_east.width = widget->allocation.width - xpaned->top_left_child_size.width - 2 * border_width - handle_size;
+ xpaned->handle_pos_east.height = handle_size;
+
+ xpaned->handle_pos_west.x = widget->allocation.x + border_width;
+ xpaned->handle_pos_west.y = xpaned->handle_pos_east.y;
+ xpaned->handle_pos_west.width = widget->allocation.width - xpaned->handle_pos_east.width - 2 * border_width - handle_size;
+ xpaned->handle_pos_west.height = handle_size;
+
+ xpaned->handle_pos_north.x = xpaned->handle_pos_east.x - handle_size;
+ xpaned->handle_pos_north.y = widget->allocation.y + border_width;
+ xpaned->handle_pos_north.width = handle_size;
+ xpaned->handle_pos_north.height = xpaned->handle_pos_east.y - widget->allocation.y - border_width;
+
+ xpaned->handle_pos_south.x = xpaned->handle_pos_north.x;
+ xpaned->handle_pos_south.y = xpaned->handle_pos_east.y + handle_size;
+ xpaned->handle_pos_south.width = handle_size;
+ xpaned->handle_pos_south.height = widget->allocation.height - xpaned->handle_pos_north.height - 2 * border_width - handle_size;
+
+
+#define CENTRUM 20
+ xpaned->handle_pos_middle.x = xpaned->handle_pos_north.x ;
+ xpaned->handle_pos_middle.y = xpaned->handle_pos_east.y ;
+ xpaned->handle_pos_middle.width = handle_size + CENTRUM ;
+ xpaned->handle_pos_middle.height = handle_size + CENTRUM;
+
+ /* set allocation for top-left child */
+ top_left_child_allocation.x = widget->allocation.x + border_width;
+ top_left_child_allocation.y = widget->allocation.y + border_width;
+ top_left_child_allocation.width = xpaned->handle_pos_west.width;
+ top_left_child_allocation.height = xpaned->handle_pos_north.height;
+
+ /* set allocation for top-right child */
+ top_right_child_allocation.x = widget->allocation.x + border_width + handle_size + top_left_child_allocation.width;
+ top_right_child_allocation.y = widget->allocation.y + border_width;
+ top_right_child_allocation.width = xpaned->handle_pos_east.width;
+ top_right_child_allocation.height = xpaned->handle_pos_north.height;
+
+ /* set allocation for bottom-left child */
+ bottom_left_child_allocation.x = xpaned->handle_pos_west.x;
+ bottom_left_child_allocation.y = xpaned->handle_pos_south.y;
+ bottom_left_child_allocation.width = xpaned->handle_pos_west.width;
+ bottom_left_child_allocation.height = xpaned->handle_pos_south.height;
+
+ /* set allocation for bottom-right child */
+ bottom_right_child_allocation.x = top_right_child_allocation.x;
+ bottom_right_child_allocation.y = bottom_left_child_allocation.y;
+ bottom_right_child_allocation.width = xpaned->handle_pos_east.width;
+ bottom_right_child_allocation.height = xpaned->handle_pos_south.height;
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ if (GTK_WIDGET_MAPPED (widget))
+ {
+ gdk_window_show (xpaned->handle_east);
+ gdk_window_show (xpaned->handle_west);
+ gdk_window_show (xpaned->handle_north);
+ gdk_window_show (xpaned->handle_south);
+ gdk_window_show (xpaned->handle_middle);
+ }
+
+ gdk_window_move_resize (xpaned->handle_east,
+ xpaned->handle_pos_east.x,
+ xpaned->handle_pos_east.y,
+ xpaned->handle_pos_east.width,
+ xpaned->handle_pos_east.height);
+
+ gdk_window_move_resize (xpaned->handle_west,
+ xpaned->handle_pos_west.x,
+ xpaned->handle_pos_west.y,
+ xpaned->handle_pos_west.width,
+ xpaned->handle_pos_west.height);
+
+ gdk_window_move_resize (xpaned->handle_north,
+ xpaned->handle_pos_north.x,
+ xpaned->handle_pos_north.y,
+ xpaned->handle_pos_north.width,
+ xpaned->handle_pos_north.height);
+
+ gdk_window_move_resize (xpaned->handle_south,
+ xpaned->handle_pos_south.x,
+ xpaned->handle_pos_south.y,
+ xpaned->handle_pos_south.width,
+ xpaned->handle_pos_south.height);
+
+ gdk_window_move_resize (xpaned->handle_middle,
+ xpaned->handle_pos_middle.x,
+ xpaned->handle_pos_middle.y,
+ xpaned->handle_pos_middle.width,
+ xpaned->handle_pos_middle.height);
+ }
+
+ /* Now allocate the childen, making sure, when resizing not to
+ * overlap the windows
+ */
+ if (GTK_WIDGET_MAPPED (widget))
+ {
+ gtk_widget_size_allocate (xpaned->top_right_child, &top_right_child_allocation);
+ gtk_widget_size_allocate (xpaned->top_left_child, &top_left_child_allocation);
+ gtk_widget_size_allocate (xpaned->bottom_left_child, &bottom_left_child_allocation);
+ gtk_widget_size_allocate (xpaned->bottom_right_child, &bottom_right_child_allocation);
+ }
+ }
+}
+
+static void gtk_xpaned_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ GtkXPaned* xpaned = GTK_XPANED (object);
+
+ switch (prop_id)
+ {
+ case PROP_X_POSITION:
+ gtk_xpaned_set_position_x (xpaned, g_value_get_int (value));
+ break;
+
+ case PROP_Y_POSITION:
+ gtk_xpaned_set_position_y (xpaned, g_value_get_int (value));
+ break;
+
+ case PROP_POSITION_SET:
+ xpaned->position_set = g_value_get_boolean (value);
+ gtk_widget_queue_resize (GTK_WIDGET (xpaned));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void gtk_xpaned_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ GtkXPaned* xpaned = GTK_XPANED (object);
+
+ switch (prop_id)
+ {
+ case PROP_X_POSITION:
+ g_value_set_int (value, xpaned->top_left_child_size.width);
+ break;
+
+ case PROP_Y_POSITION:
+ g_value_set_int (value, xpaned->top_left_child_size.height);
+ break;
+
+ case PROP_POSITION_SET:
+ g_value_set_boolean (value, xpaned->position_set);
+ break;
+
+ case PROP_MIN_X_POSITION:
+ g_value_set_int (value, xpaned->min_position.x);
+ break;
+
+ case PROP_MIN_Y_POSITION:
+ g_value_set_int (value, xpaned->min_position.y);
+ break;
+
+ case PROP_MAX_X_POSITION:
+ g_value_set_int (value, xpaned->max_position.x);
+ break;
+
+ case PROP_MAX_Y_POSITION:
+ g_value_set_int (value, xpaned->max_position.y);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void gtk_xpaned_set_child_property (GtkContainer* container,
+ GtkWidget* child,
+ guint property_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ GtkXPaned* xpaned = GTK_XPANED (container);
+ gboolean old_value = FALSE;
+ gboolean new_value = FALSE;
+
+ g_assert (child == xpaned->top_left_child ||
+ child == xpaned->top_right_child ||
+ child == xpaned->bottom_left_child ||
+ child == xpaned->bottom_right_child);
+
+ new_value = g_value_get_boolean (value);
+
+ switch (property_id)
+ {
+ case CHILD_PROP_RESIZE:
+ if (child == xpaned->top_left_child)
+ {
+ old_value = xpaned->top_left_child_resize;
+ xpaned->top_left_child_resize = new_value;
+ }
+ else if (child == xpaned->top_right_child)
+ {
+ old_value = xpaned->top_right_child_resize;
+ xpaned->top_right_child_resize = new_value;
+ }
+ else if (child == xpaned->bottom_left_child)
+ {
+ old_value = xpaned->bottom_left_child_resize;
+ xpaned->bottom_left_child_resize = new_value;
+ }
+ else if (child == xpaned->bottom_right_child)
+ {
+ old_value = xpaned->bottom_right_child_resize;
+ xpaned->bottom_right_child_resize = new_value;
+ }
+ break;
+
+ case CHILD_PROP_SHRINK :
+ if (child == xpaned->top_left_child)
+ {
+ old_value = xpaned->top_left_child_shrink;
+ xpaned->top_left_child_shrink = new_value;
+ }
+ else if (child == xpaned->top_right_child)
+ {
+ old_value = xpaned->top_right_child_shrink;
+ xpaned->top_right_child_shrink = new_value;
+ }
+ else if (child == xpaned->bottom_left_child)
+ {
+ old_value = xpaned->bottom_left_child_shrink;
+ xpaned->bottom_left_child_shrink = new_value;
+ }
+ else if (child == xpaned->bottom_right_child)
+ {
+ old_value = xpaned->bottom_right_child_shrink;
+ xpaned->bottom_right_child_shrink = new_value;
+ }
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container,
+ property_id,
+ pspec);
+ old_value = -1; /* quiet gcc */
+ break;
+ }
+
+ if (old_value != new_value)
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+}
+
+static void gtk_xpaned_get_child_property (GtkContainer* container,
+ GtkWidget* child,
+ guint property_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ GtkXPaned* xpaned = GTK_XPANED (container);
+
+ g_assert (child == xpaned->top_left_child ||
+ child == xpaned->top_right_child ||
+ child == xpaned->bottom_left_child ||
+ child == xpaned->bottom_right_child);
+
+ switch (property_id)
+ {
+ case CHILD_PROP_RESIZE :
+ if (child == xpaned->top_left_child)
+ g_value_set_boolean (value, xpaned->top_left_child_resize);
+ else if (child == xpaned->top_right_child)
+ g_value_set_boolean (value, xpaned->top_right_child_resize);
+ else if (child == xpaned->bottom_left_child)
+ g_value_set_boolean (value, xpaned->bottom_left_child_resize);
+ else if (child == xpaned->bottom_right_child)
+ g_value_set_boolean (value, xpaned->bottom_right_child_resize);
+ break;
+
+ case CHILD_PROP_SHRINK :
+ if (child == xpaned->top_left_child)
+ g_value_set_boolean (value, xpaned->top_left_child_shrink);
+ else if (child == xpaned->top_right_child)
+ g_value_set_boolean (value, xpaned->top_right_child_shrink);
+ else if (child == xpaned->bottom_left_child)
+ g_value_set_boolean (value, xpaned->bottom_left_child_shrink);
+ else if (child == xpaned->bottom_right_child)
+ g_value_set_boolean (value, xpaned->bottom_right_child_shrink);
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container,
+ property_id,
+ pspec);
+ break;
+ }
+}
+
+static void gtk_xpaned_finalize (GObject* object)
+{
+ GtkXPaned* xpaned = GTK_XPANED (object);
+
+ gtk_xpaned_set_saved_focus (xpaned, NULL);
+ gtk_xpaned_set_first_xpaned (xpaned, NULL);
+
+ g_free (xpaned->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void gtk_xpaned_realize (GtkWidget* widget)
+{
+ GtkXPaned* xpaned;
+ GdkWindowAttr attributes_east;
+ GdkWindowAttr attributes_west;
+ GdkWindowAttr attributes_north;
+ GdkWindowAttr attributes_south;
+ GdkWindowAttr attributes_middle;
+ gint attributes_mask_east;
+ gint attributes_mask_west;
+ gint attributes_mask_north;
+ gint attributes_mask_south;
+ gint attributes_mask_middle;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+ xpaned = GTK_XPANED (widget);
+
+ widget->window = gtk_widget_get_parent_window (widget);
+ g_object_ref (widget->window);
+
+ attributes_east.window_type = GDK_WINDOW_CHILD;
+ attributes_west.window_type = GDK_WINDOW_CHILD;
+ attributes_north.window_type = GDK_WINDOW_CHILD;
+ attributes_south.window_type = GDK_WINDOW_CHILD;
+ attributes_middle.window_type = GDK_WINDOW_CHILD;
+
+ attributes_east.wclass = GDK_INPUT_ONLY;
+ attributes_west.wclass = GDK_INPUT_ONLY;
+ attributes_north.wclass = GDK_INPUT_ONLY;
+ attributes_south.wclass = GDK_INPUT_ONLY;
+ attributes_middle.wclass = GDK_INPUT_ONLY;
+
+ attributes_east.x = xpaned->handle_pos_east.x;
+ attributes_east.y = xpaned->handle_pos_east.y;
+ attributes_east.width = xpaned->handle_pos_east.width;
+ attributes_east.height = xpaned->handle_pos_east.height;
+
+ attributes_west.x = xpaned->handle_pos_west.x;
+ attributes_west.y = xpaned->handle_pos_west.y;
+ attributes_west.width = xpaned->handle_pos_west.width;
+ attributes_west.height = xpaned->handle_pos_west.height;
+
+ attributes_north.x = xpaned->handle_pos_north.x;
+ attributes_north.y = xpaned->handle_pos_north.y;
+ attributes_north.width = xpaned->handle_pos_north.width;
+ attributes_north.height = xpaned->handle_pos_north.height;
+
+ attributes_south.x = xpaned->handle_pos_south.x;
+ attributes_south.y = xpaned->handle_pos_south.y;
+ attributes_south.width = xpaned->handle_pos_south.width;
+ attributes_south.height = xpaned->handle_pos_south.height;
+
+ attributes_middle.x = xpaned->handle_pos_middle.x;
+ attributes_middle.y = xpaned->handle_pos_middle.y;
+ attributes_middle.width = xpaned->handle_pos_middle.width;
+ attributes_middle.height = xpaned->handle_pos_middle.height;
+
+ attributes_east.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ xpaned->cursor_type_east);
+ attributes_west.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ xpaned->cursor_type_west);
+ attributes_north.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ xpaned->cursor_type_north);
+ attributes_south.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ xpaned->cursor_type_south);
+ attributes_middle.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+ xpaned->cursor_type_middle);
+
+ attributes_east.event_mask = gtk_widget_get_events (widget);
+ attributes_west.event_mask = gtk_widget_get_events (widget);
+ attributes_north.event_mask = gtk_widget_get_events (widget);
+ attributes_south.event_mask = gtk_widget_get_events (widget);
+ attributes_middle.event_mask = gtk_widget_get_events (widget);
+
+ attributes_east.event_mask |= (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
+ attributes_west.event_mask |= (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
+ attributes_north.event_mask |= (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
+ attributes_south.event_mask |= (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
+ attributes_middle.event_mask |= (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
+
+ attributes_mask_east = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+ attributes_mask_west = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+ attributes_mask_north = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+ attributes_mask_south = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+ attributes_mask_middle = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+
+ xpaned->handle_east = gdk_window_new (widget->window,
+ &attributes_east,
+ attributes_mask_east);
+ xpaned->handle_west = gdk_window_new (widget->window,
+ &attributes_west,
+ attributes_mask_west);
+ xpaned->handle_north = gdk_window_new (widget->window,
+ &attributes_north,
+ attributes_mask_north);
+ xpaned->handle_south = gdk_window_new (widget->window,
+ &attributes_south,
+ attributes_mask_south);
+ xpaned->handle_middle = gdk_window_new (widget->window,
+ &attributes_middle,
+ attributes_mask_middle);
+
+ gdk_window_set_user_data (xpaned->handle_east, xpaned);
+ gdk_window_set_user_data (xpaned->handle_west, xpaned);
+ gdk_window_set_user_data (xpaned->handle_north, xpaned);
+ gdk_window_set_user_data (xpaned->handle_south, xpaned);
+ gdk_window_set_user_data (xpaned->handle_middle, xpaned);
+
+ gdk_cursor_unref (attributes_east.cursor);
+ gdk_cursor_unref (attributes_west.cursor);
+ gdk_cursor_unref (attributes_north.cursor);
+ gdk_cursor_unref (attributes_south.cursor);
+ gdk_cursor_unref (attributes_middle.cursor);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+
+ if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) &&
+ xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) &&
+ xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) &&
+ xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child))
+ {
+ gdk_window_show (xpaned->handle_east);
+ gdk_window_show (xpaned->handle_west);
+ gdk_window_show (xpaned->handle_north);
+ gdk_window_show (xpaned->handle_south);
+ gdk_window_show (xpaned->handle_middle);
+ }
+}
+
+static void gtk_xpaned_unrealize (GtkWidget *widget)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ if (xpaned->xor_gc)
+ {
+ g_object_unref (xpaned->xor_gc);
+ xpaned->xor_gc = NULL;
+ }
+
+ if (xpaned->handle_east)
+ {
+ gdk_window_set_user_data (xpaned->handle_east, NULL);
+ gdk_window_destroy (xpaned->handle_east);
+ xpaned->handle_east = NULL;
+ }
+
+ if (xpaned->handle_west)
+ {
+ gdk_window_set_user_data (xpaned->handle_west, NULL);
+ gdk_window_destroy (xpaned->handle_west);
+ xpaned->handle_west = NULL;
+ }
+
+ if (xpaned->handle_north)
+ {
+ gdk_window_set_user_data (xpaned->handle_north, NULL);
+ gdk_window_destroy (xpaned->handle_north);
+ xpaned->handle_north = NULL;
+ }
+
+ if (xpaned->handle_south)
+ {
+ gdk_window_set_user_data (xpaned->handle_south, NULL);
+ gdk_window_destroy (xpaned->handle_south);
+ xpaned->handle_south = NULL;
+ }
+
+ if (xpaned->handle_middle)
+ {
+ gdk_window_set_user_data (xpaned->handle_middle, NULL);
+ gdk_window_destroy (xpaned->handle_middle);
+ xpaned->handle_middle = NULL;
+ }
+
+ gtk_xpaned_set_last_top_left_child_focus (xpaned, NULL);
+ gtk_xpaned_set_last_top_right_child_focus (xpaned, NULL);
+ gtk_xpaned_set_last_bottom_left_child_focus (xpaned, NULL);
+ gtk_xpaned_set_last_bottom_right_child_focus (xpaned, NULL);
+ gtk_xpaned_set_saved_focus (xpaned, NULL);
+ gtk_xpaned_set_first_xpaned (xpaned, NULL);
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void gtk_xpaned_map (GtkWidget* widget)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ gdk_window_show (xpaned->handle_east);
+ gdk_window_show (xpaned->handle_west);
+ gdk_window_show (xpaned->handle_north);
+ gdk_window_show (xpaned->handle_south);
+ gdk_window_show (xpaned->handle_middle);
+
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+}
+
+static void gtk_xpaned_unmap (GtkWidget* widget)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ gdk_window_hide (xpaned->handle_east);
+ gdk_window_hide (xpaned->handle_west);
+ gdk_window_hide (xpaned->handle_north);
+ gdk_window_hide (xpaned->handle_south);
+ gdk_window_hide (xpaned->handle_middle);
+
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static gboolean gtk_xpaned_expose (GtkWidget* widget,
+ GdkEventExpose* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+ gint handle_size;
+ GdkRectangle horizontalClipArea;
+ GdkRectangle verticalClipArea;
+
+ /* determine size of handle(s) */
+ gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+
+ /* I want the handle-"thickness" to be at least 3 */
+ g_assert (handle_size >= 3);
+
+ if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
+ xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) &&
+ xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) &&
+ xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) &&
+ xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child))
+ {
+ GtkStateType state;
+
+ if (gtk_widget_is_focus (widget))
+ state = GTK_STATE_SELECTED;
+ else if (xpaned->handle_prelit)
+ state = GTK_STATE_PRELIGHT;
+ else
+ state = GTK_WIDGET_STATE (widget);
+
+ horizontalClipArea.x = xpaned->handle_pos_west.x;
+ horizontalClipArea.y = xpaned->handle_pos_west.y;
+ horizontalClipArea.width = xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width;
+ horizontalClipArea.height = handle_size;
+
+ verticalClipArea.x = xpaned->handle_pos_north.x;
+ verticalClipArea.y = xpaned->handle_pos_north.y;
+ verticalClipArea.width = handle_size;
+ verticalClipArea.height = xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height;
+
+ gtk_paint_handle (widget->style,
+ widget->window,
+ state,
+ GTK_SHADOW_NONE,
+ &horizontalClipArea,
+ widget,
+ "paned",
+ xpaned->handle_pos_east.x - handle_size - 256 / 2,
+ xpaned->handle_pos_west.y + 1,
+ 256 + handle_size,
+ handle_size - 2,
+ /*xpaned->handle_pos_west.x,
+ xpaned->handle_pos_west.y + 1,
+ xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width,
+ handle_size - 2,*/
+ GTK_ORIENTATION_HORIZONTAL);
+ gtk_paint_handle (widget->style,
+ widget->window,
+ state,
+ GTK_SHADOW_NONE,
+ &verticalClipArea,
+ widget,
+ "paned",
+ xpaned->handle_pos_north.x + 1,
+ xpaned->handle_pos_south.y - handle_size - 256 / 2,
+ handle_size - 2,
+ 256 + handle_size,
+ /*xpaned->handle_pos_north.x + 1,
+ xpaned->handle_pos_north.y,
+ handle_size - 2,
+ xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height,*/
+ GTK_ORIENTATION_VERTICAL);
+ }
+
+ /* Chain up to draw children */
+ GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+
+ return FALSE;
+}
+
+static gboolean is_rtl (GtkXPaned* xpaned)
+{
+ if (gtk_widget_get_direction (GTK_WIDGET (xpaned)) == GTK_TEXT_DIR_RTL)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void update_drag (GtkXPaned* xpaned)
+{
+ GdkPoint pos;
+ gint handle_size;
+ GtkRequisition size;
+
+ gtk_widget_get_pointer (GTK_WIDGET (xpaned), &pos.x, &pos.y);
+
+ if (xpaned->in_drag_vert)
+ {
+ pos.y -= xpaned->drag_pos.y;
+
+ if (is_rtl (xpaned))
+ {
+ gtk_widget_style_get (GTK_WIDGET (xpaned),
+ "handle-size", &handle_size,
+ NULL);
+
+ size.height = GTK_WIDGET (xpaned)->allocation.height - pos.y - handle_size;
+ }
+ else
+ {
+ size.height = pos.y;
+ }
+
+ size.height -= GTK_CONTAINER (xpaned)->border_width;
+
+ size.height = CLAMP (size.height, xpaned->min_position.y, xpaned->max_position.y);
+
+ if (size.height != xpaned->top_left_child_size.height)
+ gtk_xpaned_set_position_y (xpaned, size.height);
+ }
+
+ if (xpaned->in_drag_horiz)
+ {
+ pos.x -= xpaned->drag_pos.x;
+
+ if (is_rtl (xpaned))
+ {
+ gtk_widget_style_get (GTK_WIDGET (xpaned),
+ "handle-size", &handle_size,
+ NULL);
+
+ size.width = GTK_WIDGET (xpaned)->allocation.width - pos.x - handle_size;
+ }
+ else
+ {
+ size.width = pos.x;
+ }
+
+ size.width -= GTK_CONTAINER (xpaned)->border_width;
+
+ size.width = CLAMP (size.width, xpaned->min_position.x, xpaned->max_position.x);
+
+ if (size.width != xpaned->top_left_child_size.width)
+ gtk_xpaned_set_position_x (xpaned, size.width);
+ }
+
+ if (xpaned->in_drag_vert_and_horiz)
+ {
+ pos.x -= xpaned->drag_pos.x;
+ pos.y -= xpaned->drag_pos.y;
+
+ if (is_rtl (xpaned))
+ {
+ gtk_widget_style_get (GTK_WIDGET (xpaned),
+ "handle-size", &handle_size,
+ NULL);
+
+ size.width = GTK_WIDGET (xpaned)->allocation.width - pos.x - handle_size;
+ size.height = GTK_WIDGET (xpaned)->allocation.height - pos.y - handle_size;
+ }
+ else
+ {
+ size.width = pos.x;
+ size.height = pos.y;
+ }
+
+ size.width -= GTK_CONTAINER (xpaned)->border_width;
+ size.height -= GTK_CONTAINER (xpaned)->border_width;
+
+ size.width = CLAMP (size.width, xpaned->min_position.x, xpaned->max_position.x);
+ size.height = CLAMP (size.height, xpaned->min_position.y, xpaned->max_position.y);
+
+ if (size.width != xpaned->top_left_child_size.width)
+ gtk_xpaned_set_position_x (xpaned, size.width);
+
+ if (size.height != xpaned->top_left_child_size.height)
+ gtk_xpaned_set_position_y (xpaned, size.height);
+ }
+}
+
+static gboolean gtk_xpaned_enter (GtkWidget* widget, GdkEventCrossing* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ if (xpaned->in_drag_vert ||
+ xpaned->in_drag_horiz ||
+ xpaned->in_drag_vert_and_horiz)
+ update_drag (xpaned);
+ else
+ {
+ xpaned->handle_prelit = TRUE;
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_east.x,
+ xpaned->handle_pos_east.y,
+ xpaned->handle_pos_east.width,
+ xpaned->handle_pos_east.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_west.x,
+ xpaned->handle_pos_west.y,
+ xpaned->handle_pos_west.width,
+ xpaned->handle_pos_west.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_north.x,
+ xpaned->handle_pos_north.y,
+ xpaned->handle_pos_north.width,
+ xpaned->handle_pos_north.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_south.x,
+ xpaned->handle_pos_south.y,
+ xpaned->handle_pos_south.width,
+ xpaned->handle_pos_south.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_middle.x,
+ xpaned->handle_pos_middle.y,
+ xpaned->handle_pos_middle.width,
+ xpaned->handle_pos_middle.height);
+ }
+
+ return TRUE;
+}
+
+static gboolean gtk_xpaned_leave (GtkWidget* widget, GdkEventCrossing* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ if (xpaned->in_drag_vert ||
+ xpaned->in_drag_horiz ||
+ xpaned->in_drag_vert_and_horiz)
+ update_drag (xpaned);
+ else
+ {
+ xpaned->handle_prelit = FALSE;
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_east.x,
+ xpaned->handle_pos_east.y,
+ xpaned->handle_pos_east.width,
+ xpaned->handle_pos_east.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_west.x,
+ xpaned->handle_pos_west.y,
+ xpaned->handle_pos_west.width,
+ xpaned->handle_pos_west.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_north.x,
+ xpaned->handle_pos_north.y,
+ xpaned->handle_pos_north.width,
+ xpaned->handle_pos_north.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_south.x,
+ xpaned->handle_pos_south.y,
+ xpaned->handle_pos_south.width,
+ xpaned->handle_pos_south.height);
+
+ gtk_widget_queue_draw_area (widget,
+ xpaned->handle_pos_middle.x,
+ xpaned->handle_pos_middle.y,
+ xpaned->handle_pos_middle.width,
+ xpaned->handle_pos_middle.height);
+ }
+
+ return TRUE;
+}
+
+static gboolean gtk_xpaned_focus (GtkWidget* widget, GtkDirectionType direction)
+{
+ gboolean retval;
+
+ /* This is a hack, but how can this be done without
+ * excessive cut-and-paste from gtkcontainer.c?
+ */
+
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
+ retval = (* GTK_WIDGET_CLASS (parent_class)->focus) (widget, direction);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+
+ return retval;
+}
+
+static gboolean gtk_xpaned_button_press (GtkWidget* widget,
+ GdkEventButton* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ /* if any child is currently maximized, jump right back */
+ if (xpaned->maximized[GTK_XPANED_TOP_LEFT] ||
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ return FALSE;
+
+ /* if user is dragging the handles around */
+ if (!xpaned->in_drag_vert_and_horiz &&
+ event->window != xpaned->handle_east &&
+ event->window != xpaned->handle_west &&
+ event->window != xpaned->handle_north &&
+ event->window != xpaned->handle_south &&
+ event->window == xpaned->handle_middle &&
+ event->button == 1)
+ {
+ xpaned->in_drag_vert_and_horiz = TRUE;
+
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ if (gdk_pointer_grab (xpaned->handle_middle,
+ FALSE,
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ NULL,
+ event->time) == GDK_GRAB_SUCCESS)
+ {
+ }
+
+ xpaned->drag_pos.x = event->x;
+ xpaned->drag_pos.y = event->y;
+
+ return TRUE;
+ }
+ else if (!xpaned->in_drag_vert &&
+ event->window == xpaned->handle_east &&
+ event->window != xpaned->handle_west &&
+ event->window != xpaned->handle_north &&
+ event->window != xpaned->handle_south &&
+ event->window != xpaned->handle_middle &&
+ event->button == 1)
+ {
+ xpaned->in_drag_vert = TRUE;
+
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ if (gdk_pointer_grab (xpaned->handle_east,
+ FALSE,
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ NULL,
+ event->time) == GDK_GRAB_SUCCESS)
+ {
+ }
+
+ xpaned->drag_pos.y = event->y;
+
+ return TRUE;
+ }
+ else if (!xpaned->in_drag_vert &&
+ event->window != xpaned->handle_east &&
+ event->window == xpaned->handle_west &&
+ event->window != xpaned->handle_north &&
+ event->window != xpaned->handle_south &&
+ event->window != xpaned->handle_middle &&
+ event->button == 1)
+ {
+ xpaned->in_drag_vert = TRUE;
+
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ if (gdk_pointer_grab (xpaned->handle_west,
+ FALSE,
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ NULL,
+ event->time) == GDK_GRAB_SUCCESS)
+ {
+ }
+
+ xpaned->drag_pos.y = event->y;
+
+ return TRUE;
+ }
+ else if (!xpaned->in_drag_horiz &&
+ event->window != xpaned->handle_east &&
+ event->window != xpaned->handle_west &&
+ event->window == xpaned->handle_north &&
+ event->window != xpaned->handle_south &&
+ event->window != xpaned->handle_middle &&
+ event->button == 1)
+ {
+ xpaned->in_drag_horiz = TRUE;
+
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ if (gdk_pointer_grab (xpaned->handle_north,
+ FALSE,
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ NULL,
+ event->time) == GDK_GRAB_SUCCESS)
+ {
+ }
+
+ xpaned->drag_pos.x = event->x;
+
+ return TRUE;
+ }
+ else if (!xpaned->in_drag_horiz &&
+ event->window != xpaned->handle_east &&
+ event->window != xpaned->handle_west &&
+ event->window != xpaned->handle_north &&
+ event->window == xpaned->handle_south &&
+ event->window != xpaned->handle_middle &&
+ event->button == 1)
+ {
+ xpaned->in_drag_horiz = TRUE;
+
+ /* We need a server grab here, not gtk_grab_add(), since
+ * we don't want to pass events on to the widget's children */
+ if (gdk_pointer_grab (xpaned->handle_south,
+ FALSE,
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ NULL,
+ event->time) == GDK_GRAB_SUCCESS)
+ {
+ }
+
+ xpaned->drag_pos.x = event->x;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean gtk_xpaned_button_release (GtkWidget* widget,
+ GdkEventButton* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ if (xpaned->in_drag_vert && (event->button == 1))
+ {
+ xpaned->in_drag_vert = FALSE;
+ xpaned->drag_pos.y = -1;
+ xpaned->position_set = TRUE;
+ gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+ event->time);
+ return TRUE;
+ }
+ else if (xpaned->in_drag_horiz && (event->button == 1))
+ {
+ xpaned->in_drag_horiz = FALSE;
+ xpaned->drag_pos.x = -1;
+ xpaned->position_set = TRUE;
+ gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+ event->time);
+ return TRUE;
+ }
+ else if (xpaned->in_drag_vert_and_horiz && (event->button == 1))
+ {
+ xpaned->in_drag_vert_and_horiz = FALSE;
+ xpaned->drag_pos.x = -1;
+ xpaned->drag_pos.y = -1;
+ xpaned->position_set = TRUE;
+ gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+ event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean gtk_xpaned_motion (GtkWidget* widget, GdkEventMotion* event)
+{
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ if (xpaned->in_drag_vert ||
+ xpaned->in_drag_horiz ||
+ xpaned->in_drag_vert_and_horiz)
+
+ {
+ update_drag (xpaned);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void gtk_xpaned_add_top_left (GtkXPaned* xpaned, GtkWidget *widget)
+{
+ gtk_xpaned_pack_top_left (xpaned, widget, FALSE, TRUE);
+}
+
+void gtk_xpaned_add_top_right (GtkXPaned* xpaned, GtkWidget *widget)
+{
+ gtk_xpaned_pack_top_right (xpaned, widget, FALSE, TRUE);
+}
+
+void gtk_xpaned_add_bottom_left (GtkXPaned* xpaned, GtkWidget *widget)
+{
+ gtk_xpaned_pack_bottom_left (xpaned, widget, FALSE, TRUE);
+}
+
+void gtk_xpaned_add_bottom_right (GtkXPaned* xpaned, GtkWidget *widget)
+{
+ gtk_xpaned_pack_bottom_right (xpaned, widget, FALSE, TRUE);
+}
+
+void gtk_xpaned_pack_top_left (GtkXPaned* xpaned,
+ GtkWidget* child,
+ gboolean resize,
+ gboolean shrink)
+{
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ if (!xpaned->top_left_child)
+ {
+ xpaned->top_left_child = child;
+ xpaned->top_left_child_resize = resize;
+ xpaned->top_left_child_shrink = shrink;
+
+ gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+ }
+}
+
+void gtk_xpaned_pack_top_right (GtkXPaned* xpaned,
+ GtkWidget* child,
+ gboolean resize,
+ gboolean shrink)
+{
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ if (!xpaned->top_right_child)
+ {
+ xpaned->top_right_child = child;
+ xpaned->top_right_child_resize = resize;
+ xpaned->top_right_child_shrink = shrink;
+
+ gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+ }
+}
+
+void gtk_xpaned_pack_bottom_left (GtkXPaned* xpaned,
+ GtkWidget* child,
+ gboolean resize,
+ gboolean shrink)
+{
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ if (!xpaned->bottom_left_child)
+ {
+ xpaned->bottom_left_child = child;
+ xpaned->bottom_left_child_resize = resize;
+ xpaned->bottom_left_child_shrink = shrink;
+
+ gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+ }
+}
+
+void gtk_xpaned_pack_bottom_right (GtkXPaned* xpaned,
+ GtkWidget* child,
+ gboolean resize,
+ gboolean shrink)
+{
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ if (!xpaned->bottom_right_child)
+ {
+ xpaned->bottom_right_child = child;
+ xpaned->bottom_right_child_resize = resize;
+ xpaned->bottom_right_child_shrink = shrink;
+
+ gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+ }
+}
+
+static void gtk_xpaned_add (GtkContainer* container, GtkWidget* widget)
+{
+ GtkXPaned* xpaned;
+
+ g_return_if_fail (GTK_IS_XPANED (container));
+
+ xpaned = GTK_XPANED (container);
+
+ if (!xpaned->top_left_child)
+ gtk_xpaned_add_top_left (xpaned, widget);
+ else if (!xpaned->top_right_child)
+ gtk_xpaned_add_top_right (xpaned, widget);
+ else if (!xpaned->bottom_left_child)
+ gtk_xpaned_add_bottom_left (xpaned, widget);
+ else if (!xpaned->bottom_right_child)
+ gtk_xpaned_add_bottom_right (xpaned, widget);
+ else
+ g_warning ("GtkXPaned cannot have more than 4 children\n");
+}
+
+static void gtk_xpaned_remove (GtkContainer* container, GtkWidget* widget)
+{
+ GtkXPaned* xpaned;
+ gboolean was_visible;
+
+ xpaned = GTK_XPANED (container);
+ was_visible = GTK_WIDGET_VISIBLE (widget);
+
+ if (xpaned->top_left_child == widget)
+ {
+ gtk_widget_unparent (widget);
+
+ xpaned->top_left_child = NULL;
+
+ if (was_visible && GTK_WIDGET_VISIBLE (container))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else if (xpaned->top_right_child == widget)
+ {
+ gtk_widget_unparent (widget);
+
+ xpaned->top_right_child = NULL;
+
+ if (was_visible && GTK_WIDGET_VISIBLE (container))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else if (xpaned->bottom_left_child == widget)
+ {
+ gtk_widget_unparent (widget);
+
+ xpaned->bottom_left_child = NULL;
+
+ if (was_visible && GTK_WIDGET_VISIBLE (container))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else if (xpaned->bottom_right_child == widget)
+ {
+ gtk_widget_unparent (widget);
+
+ xpaned->bottom_right_child = NULL;
+
+ if (was_visible && GTK_WIDGET_VISIBLE (container))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else
+ g_warning ("GtkXPaned has no more children attached\n");
+
+}
+
+static void gtk_xpaned_forall (GtkContainer* container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GtkXPaned* xpaned;
+
+ g_return_if_fail (callback != NULL);
+
+ xpaned = GTK_XPANED (container);
+
+ if (xpaned->top_left_child)
+ (*callback) (xpaned->top_left_child, callback_data);
+ if (xpaned->top_right_child)
+ (*callback) (xpaned->top_right_child, callback_data);
+ if (xpaned->bottom_left_child)
+ (*callback) (xpaned->bottom_left_child, callback_data);
+ if (xpaned->bottom_right_child)
+ (*callback) (xpaned->bottom_right_child, callback_data);
+}
+
+/**
+ * gtk_xpaned_get_position_x:
+ * @paned: a #GtkXPaned widget
+ *
+ * Obtains the x-position of the divider.
+ *
+ * Return value: x-position of the divider
+ **/
+gint gtk_xpaned_get_position_x (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), 0);
+
+ return xpaned->top_left_child_size.width;
+}
+
+/**
+ * gtk_xpaned_get_position_y:
+ * @paned: a #GtkXPaned widget
+ *
+ * Obtains the y-position of the divider.
+ *
+ * Return value: y-position of the divider
+ **/
+gint gtk_xpaned_get_position_y (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), 0);
+
+ return xpaned->top_left_child_size.height;
+}
+
+/**
+ * gtk_xpaned_set_position_x:
+ * @paned: a #GtkXPaned widget
+ * @xposition: pixel x-position of divider, a negative values
+ * of a component mean that the position is unset.
+ *
+ * Sets the x-position of the divider between the four panes.
+ **/
+void gtk_xpaned_set_position_x (GtkXPaned* xpaned, gint xposition)
+{
+ GObject* object;
+
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+
+ /* if any child is currently maximized, jump right back */
+ if (xpaned->maximized[GTK_XPANED_TOP_LEFT] ||
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ return;
+
+ object = G_OBJECT (xpaned);
+
+ if (xposition >= 0)
+ {
+ /* We don't clamp here - the assumption is that
+ * if the total allocation changes at the same time
+ * as the position, the position set is with reference
+ * to the new total size. If only the position changes,
+ * then clamping will occur in gtk_paned_compute_position()
+ */
+
+ xpaned->top_left_child_size.width = xposition;
+ xpaned->position_set = TRUE;
+ }
+ else
+ {
+ xpaned->position_set = FALSE;
+ }
+
+ g_object_freeze_notify (object);
+ g_object_notify (object, "x-position");
+ g_object_notify (object, "position-set");
+ g_object_thaw_notify (object);
+
+ gtk_widget_queue_resize (GTK_WIDGET (xpaned));
+}
+
+/**
+ * gtk_xpaned_set_position_y:
+ * @paned: a #GtkXPaned widget
+ * @yposition: pixel y-position of divider, a negative values
+ * of a component mean that the position is unset.
+ *
+ * Sets the y-position of the divider between the four panes.
+ **/
+void gtk_xpaned_set_position_y (GtkXPaned* xpaned, gint yposition)
+{
+ GObject* object;
+
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+
+ /* if any child is currently maximized, jump right back */
+ if (xpaned->maximized[GTK_XPANED_TOP_LEFT] ||
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] ||
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ return;
+
+ object = G_OBJECT (xpaned);
+
+ if (yposition >= 0)
+ {
+ /* We don't clamp here - the assumption is that
+ * if the total allocation changes at the same time
+ * as the position, the position set is with reference
+ * to the new total size. If only the position changes,
+ * then clamping will occur in gtk_paned_compute_position()
+ */
+
+ xpaned->top_left_child_size.height = yposition;
+ xpaned->position_set = TRUE;
+ }
+ else
+ {
+ xpaned->position_set = FALSE;
+ }
+
+ g_object_freeze_notify (object);
+ g_object_notify (object, "y-position");
+ g_object_notify (object, "position-set");
+ g_object_thaw_notify (object);
+
+ gtk_widget_queue_resize (GTK_WIDGET (xpaned));
+}
+
+/* this call is private and only intended for internal use! */
+void gtk_xpaned_save_unmaximized_x (GtkXPaned* xpaned)
+{
+ xpaned->unmaximized_position.x = gtk_xpaned_get_position_x (xpaned);
+}
+
+/* this call is private and only intended for internal use! */
+void gtk_xpaned_save_unmaximized_y (GtkXPaned* xpaned)
+{
+ xpaned->unmaximized_position.y = gtk_xpaned_get_position_y (xpaned);
+}
+
+/* this call is private and only intended for internal use! */
+gint gtk_xpaned_fetch_unmaximized_x (GtkXPaned* xpaned)
+{
+ return xpaned->unmaximized_position.x;
+}
+
+/* this call is private and only intended for internal use! */
+gint gtk_xpaned_fetch_unmaximized_y (GtkXPaned* xpaned)
+{
+ return xpaned->unmaximized_position.y;
+}
+
+/**
+ * gtk_xpaned_get_top_left_child:
+ * @xpaned: a #GtkXPaned widget
+ *
+ * Obtains the top-left child of the xpaned widget.
+ *
+ * Return value: top-left child, or %NULL if it is not set.
+ *
+ * Since: 2.4
+ **/
+GtkWidget* gtk_xpaned_get_top_left_child (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL);
+
+ return xpaned->top_left_child;
+}
+
+/**
+ * gtk_xpaned_get_top_right_child:
+ * @xpaned: a #GtkXPaned widget
+ *
+ * Obtains the top-right child of the xpaned widget.
+ *
+ * Return value: top-right child, or %NULL if it is not set.
+ *
+ * Since: 2.4
+ **/
+GtkWidget* gtk_xpaned_get_top_right_child (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL);
+
+ return xpaned->top_right_child;
+}
+
+/**
+ * gtk_xpaned_get_bottom_left_child:
+ * @xpaned: a #GtkXPaned widget
+ *
+ * Obtains the bottom-left child of the xpaned widget.
+ *
+ * Return value: bottom-left child, or %NULL if it is not set.
+ *
+ * Since: 2.4
+ **/
+GtkWidget* gtk_xpaned_get_bottom_left_child (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL);
+
+ return xpaned->bottom_left_child;
+}
+
+/**
+ * gtk_xpaned_get_bottom_right_child:
+ * @xpaned: a #GtkXPaned widget
+ *
+ * Obtains the bottom-right child of the xpaned widget.
+ *
+ * Return value: bottom-right child, or %NULL if it is not set.
+ *
+ * Since: 2.4
+ **/
+GtkWidget* gtk_xpaned_get_bottom_right_child (GtkXPaned* xpaned)
+{
+ g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL);
+
+ return xpaned->bottom_right_child;
+}
+
+gboolean gtk_xpaned_maximize_top_left (GtkXPaned* xpaned, gboolean maximize)
+{
+ if (maximize)
+ {
+ /* see if any child is already maximized */
+ if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_TOP_RIGHT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ {
+ /* save current position */
+ gtk_xpaned_save_unmaximized_x (xpaned);
+ gtk_xpaned_save_unmaximized_y (xpaned);
+
+ /* set new maximized position */
+ gtk_xpaned_set_position_x (xpaned, xpaned->max_position.x);
+ gtk_xpaned_set_position_y (xpaned, xpaned->max_position.y);
+
+ /* mark maximized flag for top-left child */
+ xpaned->maximized[GTK_XPANED_TOP_LEFT] = TRUE;
+
+ return TRUE;
+ }
+ /* already one child maximized, report error */
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* verify that top-left child is really currently maximized */
+ if (xpaned->maximized[GTK_XPANED_TOP_LEFT])
+ {
+ /* clear maximized flat for top-left child */
+ xpaned->maximized[GTK_XPANED_TOP_LEFT] = FALSE;
+
+ /* restore unmaximized position */
+ gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned));
+ gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned));
+
+ return TRUE;
+ }
+ /* top-left child is currently not maximized, report error */
+ else
+ return FALSE;
+ }
+}
+
+gboolean gtk_xpaned_maximize_top_right (GtkXPaned* xpaned, gboolean maximize)
+{
+ if (maximize)
+ {
+ /* see if any child is already maximized */
+ if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_TOP_RIGHT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ {
+ /* save current position */
+ gtk_xpaned_save_unmaximized_x (xpaned);
+ gtk_xpaned_save_unmaximized_y (xpaned);
+
+ /* set new maximized position */
+ gtk_xpaned_set_position_x (xpaned, xpaned->min_position.x);
+ gtk_xpaned_set_position_y (xpaned, xpaned->max_position.y);
+
+ /* mark maximized flag for top-right child */
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] = TRUE;
+
+ return TRUE;
+ }
+ /* already one child maximized, report error */
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* verify that top-right child is really currently maximized */
+ if (xpaned->maximized[GTK_XPANED_TOP_RIGHT])
+ {
+ /* clear maximized flat for top-right child */
+ xpaned->maximized[GTK_XPANED_TOP_RIGHT] = FALSE;
+
+ /* restore unmaximized position */
+ gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned));
+ gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned));
+
+ return TRUE;
+ }
+ /* top-right child is currently not maximized, report error */
+ else
+ return FALSE;
+ }
+}
+
+gboolean gtk_xpaned_maximize_bottom_left (GtkXPaned* xpaned, gboolean maximize)
+{
+ if (maximize)
+ {
+ /* see if any child is already maximized */
+ if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_TOP_RIGHT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ {
+ /* save current position */
+ gtk_xpaned_save_unmaximized_x (xpaned);
+ gtk_xpaned_save_unmaximized_y (xpaned);
+
+ /* set new maximized position */
+ gtk_xpaned_set_position_x (xpaned, xpaned->max_position.x);
+ gtk_xpaned_set_position_y (xpaned, xpaned->min_position.y);
+
+ /* mark maximized flag for bottom-left child */
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = TRUE;
+
+ return TRUE;
+ }
+ /* already one child maximized, report error */
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* verify that bottom-left child is really currently maximized */
+ if (xpaned->maximized[GTK_XPANED_BOTTOM_LEFT])
+ {
+ /* clear maximized flat for bottom-left child */
+ xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = FALSE;
+
+ /* restore unmaximized position */
+ gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned));
+ gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned));
+
+ return TRUE;
+ }
+ /* bottom-left child is currently not maximized, report error */
+ else
+ return FALSE;
+ }
+}
+
+gboolean gtk_xpaned_maximize_bottom_right (GtkXPaned* xpaned, gboolean maximize)
+{
+ if (maximize)
+ {
+ /* see if any child is already maximized */
+ if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_TOP_RIGHT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] &&
+ !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ {
+ /* save current position */
+ gtk_xpaned_save_unmaximized_x (xpaned);
+ gtk_xpaned_save_unmaximized_y (xpaned);
+
+ /* set new maximized position */
+ gtk_xpaned_set_position_x (xpaned, xpaned->min_position.x);
+ gtk_xpaned_set_position_y (xpaned, xpaned->min_position.y);
+
+ /* mark maximized flag for bottom-right child */
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = TRUE;
+
+ return TRUE;
+ }
+ /* already one child maximized, report error */
+ else
+ return FALSE;
+ }
+ else
+ {
+ /* verify that bottom-right child is really currently maximized */
+ if (xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT])
+ {
+ /* clear maximized flat for bottom-right child */
+ xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = FALSE;
+
+ /* restore unmaximized position */
+ gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned));
+ gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned));
+
+ return TRUE;
+ }
+ /* bottom-right child is currently not maximized, report error */
+ else
+ return FALSE;
+ }
+}
+
+void
+gtk_xpaned_compute_position (GtkXPaned* xpaned,
+ const GtkAllocation* allocation,
+ GtkRequisition* top_left_child_req,
+ GtkRequisition* top_right_child_req,
+ GtkRequisition* bottom_left_child_req,
+ GtkRequisition* bottom_right_child_req)
+{
+ GdkPoint old_position;
+ GdkPoint old_min_position;
+ GdkPoint old_max_position;
+ gint handle_size;
+ gint border_width = GTK_CONTAINER (xpaned)->border_width;
+ float fX;
+ float fY;
+
+ g_return_if_fail (GTK_IS_XPANED (xpaned));
+
+ old_position.x = xpaned->top_left_child_size.width;
+ old_position.y = xpaned->top_left_child_size.height;
+ old_min_position.x = xpaned->min_position.x;
+ old_min_position.y = xpaned->min_position.y;
+ old_max_position.x = xpaned->max_position.x;
+ old_max_position.y = xpaned->max_position.y;
+
+ fX = 100.0f * (float) old_position.x / (float) allocation->width;
+ fY = 100.0f * (float) old_position.y / (float) allocation->height;
+
+ xpaned->min_position.x = xpaned->top_left_child_shrink ? 0 : top_left_child_req->width;
+ xpaned->min_position.y = xpaned->top_left_child_shrink ? 0 : top_left_child_req->height;
+
+ gtk_widget_style_get (GTK_WIDGET (xpaned), "handle-size", &handle_size, NULL);
+
+ xpaned->max_position.x = allocation->width - 2 * border_width - handle_size;
+ xpaned->max_position.y = allocation->height - 2 * border_width - handle_size;
+ if (!xpaned->top_left_child_shrink)
+ xpaned->max_position.x = MAX (1, xpaned->max_position.x - top_left_child_req->width);
+ xpaned->max_position.x = MAX (xpaned->min_position.x, xpaned->max_position.x);
+
+ if (!xpaned->position_set)
+ {
+ if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize)
+ {
+ xpaned->top_left_child_size.width = MAX (0, allocation->width - top_right_child_req->width);
+ xpaned->top_left_child_size.height = MAX (0, allocation->height - top_right_child_req->height);
+ }
+ else if (!xpaned->top_left_child_resize && xpaned->top_right_child_resize)
+ {
+ xpaned->top_left_child_size.width = top_left_child_req->width;
+ xpaned->top_left_child_size.height = top_left_child_req->height;
+ }
+ else if (top_left_child_req->width + top_right_child_req->width != 0)
+ {
+ xpaned->top_left_child_size.width = allocation->width * ((gdouble)top_left_child_req->width / (top_left_child_req->width + top_right_child_req->width)) + 0.5;
+ }
+ else if (top_left_child_req->height + top_right_child_req->height != 0)
+ {
+ xpaned->top_left_child_size.height = allocation->height * ((gdouble)top_left_child_req->height / (top_left_child_req->height + top_right_child_req->height)) + 0.5;
+ }
+ else
+ {
+ xpaned->top_left_child_size.width = allocation->width * 0.5 + 0.5;
+ xpaned->top_left_child_size.height = allocation->height * 0.5 + 0.5;
+ }
+ }
+ else
+ {
+ /* If the position was set before the initial allocation.
+ ** (paned->last_allocation <= 0) just clamp it and leave it. */
+ if (xpaned->last_allocation.width > 0)
+ {
+ if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize)
+ {
+ xpaned->top_left_child_size.width += allocation->width
+ - xpaned->last_allocation.width;
+
+ xpaned->top_left_child_size.height += allocation->height
+ - xpaned->last_allocation.height;
+ }
+ else if (!(!xpaned->top_left_child_resize && xpaned->top_right_child_resize))
+ {
+ xpaned->top_left_child_size.width = allocation->width
+ * ((gdouble) xpaned->top_left_child_size.width / (xpaned->last_allocation.width))
+ + 0.5;
+
+ xpaned->top_left_child_size.height = allocation->height
+ * ((gdouble) xpaned->top_left_child_size.height / (xpaned->last_allocation.height))
+ + 0.5;
+ }
+ }
+ if (xpaned->last_allocation.height > 0)
+ {
+ if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize)
+ {
+ xpaned->top_left_child_size.width += allocation->width - xpaned->last_allocation.width;
+ xpaned->top_left_child_size.height += allocation->height - xpaned->last_allocation.height;
+ }
+ else if (!(!xpaned->top_left_child_resize && xpaned->top_right_child_resize))
+ {
+ xpaned->top_left_child_size.width = allocation->width * ((gdouble) xpaned->top_left_child_size.width / (xpaned->last_allocation.width)) + 0.5;
+ xpaned->top_left_child_size.height = allocation->height * ((gdouble) xpaned->top_left_child_size.height / (xpaned->last_allocation.height)) + 0.5;
+ }
+ }
+
+ }
+
+ xpaned->top_left_child_size.width = CLAMP (xpaned->top_left_child_size.width,
+ xpaned->min_position.x,
+ xpaned->max_position.x);
+ xpaned->top_left_child_size.height = CLAMP (xpaned->top_left_child_size.height,
+ xpaned->min_position.y,
+ xpaned->max_position.y);
+
+ xpaned->top_right_child_size.width = CLAMP (xpaned->top_right_child_size.width,
+ xpaned->min_position.x,
+ xpaned->max_position.x);
+ xpaned->top_right_child_size.height = CLAMP (xpaned->top_right_child_size.height,
+ xpaned->min_position.y,
+ xpaned->max_position.y);
+
+ xpaned->bottom_left_child_size.width = CLAMP (xpaned->bottom_left_child_size.width,
+ xpaned->min_position.x,
+ xpaned->max_position.x);
+ xpaned->bottom_left_child_size.height = CLAMP (xpaned->bottom_left_child_size.height,
+ xpaned->min_position.y,
+ xpaned->max_position.y);
+
+ xpaned->bottom_right_child_size.width = CLAMP (xpaned->bottom_right_child_size.width,
+ xpaned->min_position.x,
+ xpaned->max_position.x);
+ xpaned->bottom_right_child_size.height = CLAMP (xpaned->bottom_right_child_size.height,
+ xpaned->min_position.y,
+ xpaned->max_position.y);
+
+ gtk_widget_set_child_visible (xpaned->top_left_child, TRUE);
+ gtk_widget_set_child_visible (xpaned->top_right_child, TRUE);
+ gtk_widget_set_child_visible (xpaned->bottom_left_child, TRUE);
+ gtk_widget_set_child_visible (xpaned->bottom_right_child, TRUE);
+
+ g_object_freeze_notify (G_OBJECT (xpaned));
+
+ if (xpaned->top_left_child_size.width != old_position.x)
+ g_object_notify (G_OBJECT (xpaned), "x-position");
+ if (xpaned->top_left_child_size.height != old_position.y)
+ g_object_notify (G_OBJECT (xpaned), "y-position");
+
+ if (xpaned->top_right_child_size.width != old_position.x)
+ g_object_notify (G_OBJECT (xpaned), "x-position");
+ if (xpaned->top_right_child_size.height != old_position.y)
+ g_object_notify (G_OBJECT (xpaned), "y-position");
+
+ if (xpaned->bottom_left_child_size.width != old_position.x)
+ g_object_notify (G_OBJECT (xpaned), "x-position");
+ if (xpaned->bottom_left_child_size.height != old_position.y)
+ g_object_notify (G_OBJECT (xpaned), "y-position");
+
+ if (xpaned->bottom_right_child_size.width != old_position.x)
+ g_object_notify (G_OBJECT (xpaned), "x-position");
+ if (xpaned->bottom_right_child_size.height != old_position.y)
+ g_object_notify (G_OBJECT (xpaned), "y-position");
+
+ if (xpaned->min_position.x != old_min_position.x)
+ g_object_notify (G_OBJECT (xpaned), "min-x-position");
+ if (xpaned->min_position.y != old_min_position.y)
+ g_object_notify (G_OBJECT (xpaned), "min-y-position");
+
+ if (xpaned->max_position.x != old_max_position.x)
+ g_object_notify (G_OBJECT (xpaned), "max-y-position");
+ if (xpaned->max_position.y != old_max_position.y)
+ g_object_notify (G_OBJECT (xpaned), "max-y-position");
+
+ g_object_thaw_notify (G_OBJECT (xpaned));
+
+ xpaned->last_allocation.width = allocation->width;
+ xpaned->last_allocation.height = allocation->height;
+
+ fX = 100.0f * (float) old_position.x / (float) allocation->width;
+ fY = 100.0f * (float) old_position.y / (float) allocation->height;
+}
+
+static void gtk_xpaned_set_saved_focus (GtkXPaned* xpaned, GtkWidget* widget)
+{
+ if (xpaned->priv->saved_focus)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->priv->saved_focus),
+ (gpointer *)&(xpaned->priv->saved_focus));
+
+ xpaned->priv->saved_focus = widget;
+
+ if (xpaned->priv->saved_focus)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->priv->saved_focus),
+ (gpointer *)&(xpaned->priv->saved_focus));
+}
+
+static void gtk_xpaned_set_first_xpaned (GtkXPaned* xpaned,
+ GtkXPaned* first_xpaned)
+{
+ if (xpaned->priv->first_xpaned)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->priv->first_xpaned),
+ (gpointer *)&(xpaned->priv->first_xpaned));
+
+ xpaned->priv->first_xpaned = first_xpaned;
+
+ if (xpaned->priv->first_xpaned)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->priv->first_xpaned),
+ (gpointer *)&(xpaned->priv->first_xpaned));
+}
+
+static void gtk_xpaned_set_last_top_left_child_focus (GtkXPaned* xpaned,
+ GtkWidget* widget)
+{
+ if (xpaned->last_top_left_child_focus)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->last_top_left_child_focus),
+ (gpointer *)&(xpaned->last_top_left_child_focus));
+
+ xpaned->last_top_left_child_focus = widget;
+
+ if (xpaned->last_top_left_child_focus)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->last_top_left_child_focus),
+ (gpointer *)&(xpaned->last_top_left_child_focus));
+}
+
+static void gtk_xpaned_set_last_top_right_child_focus (GtkXPaned* xpaned,
+ GtkWidget *widget)
+{
+ if (xpaned->last_top_right_child_focus)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->last_top_right_child_focus),
+ (gpointer *)&(xpaned->last_top_right_child_focus));
+
+ xpaned->last_top_right_child_focus = widget;
+
+ if (xpaned->last_top_right_child_focus)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->last_top_right_child_focus),
+ (gpointer *)&(xpaned->last_top_right_child_focus));
+}
+
+static void gtk_xpaned_set_last_bottom_left_child_focus (GtkXPaned* xpaned,
+ GtkWidget *widget)
+{
+ if (xpaned->last_bottom_left_child_focus)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->last_bottom_left_child_focus),
+ (gpointer *)&(xpaned->last_bottom_left_child_focus));
+
+ xpaned->last_bottom_left_child_focus = widget;
+
+ if (xpaned->last_bottom_left_child_focus)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->last_bottom_left_child_focus),
+ (gpointer *)&(xpaned->last_bottom_left_child_focus));
+}
+
+static void gtk_xpaned_set_last_bottom_right_child_focus (GtkXPaned* xpaned,
+ GtkWidget *widget)
+{
+ if (xpaned->last_bottom_right_child_focus)
+ g_object_remove_weak_pointer (G_OBJECT (xpaned->last_bottom_right_child_focus),
+ (gpointer *)&(xpaned->last_bottom_right_child_focus));
+
+ xpaned->last_bottom_right_child_focus = widget;
+
+ if (xpaned->last_bottom_right_child_focus)
+ g_object_add_weak_pointer (G_OBJECT (xpaned->last_bottom_right_child_focus),
+ (gpointer *)&(xpaned->last_bottom_right_child_focus));
+}
+
+static GtkWidget* xpaned_get_focus_widget (GtkXPaned* xpaned)
+{
+ GtkWidget* toplevel;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned));
+ if (GTK_WIDGET_TOPLEVEL (toplevel))
+ return GTK_WINDOW (toplevel)->focus_widget;
+
+ return NULL;
+}
+
+static void gtk_xpaned_set_focus_child (GtkContainer* container,
+ GtkWidget* focus_child)
+{
+ GtkXPaned* xpaned;
+
+ g_return_if_fail (GTK_IS_XPANED (container));
+
+ xpaned = GTK_XPANED (container);
+
+ if (focus_child == NULL)
+ {
+ GtkWidget* last_focus;
+ GtkWidget* w;
+
+ last_focus = xpaned_get_focus_widget (xpaned);
+
+ if (last_focus)
+ {
+ /* If there is one or more paned widgets between us and the
+ * focus widget, we want the topmost of those as last_focus
+ */
+ for (w = last_focus; w != GTK_WIDGET (xpaned); w = w->parent)
+ if (GTK_IS_XPANED (w))
+ last_focus = w;
+
+ if (container->focus_child == xpaned->top_left_child)
+ gtk_xpaned_set_last_top_left_child_focus (xpaned, last_focus);
+ else if (container->focus_child == xpaned->top_right_child)
+ gtk_xpaned_set_last_top_right_child_focus (xpaned, last_focus);
+ else if (container->focus_child == xpaned->bottom_left_child)
+ gtk_xpaned_set_last_bottom_left_child_focus (xpaned, last_focus);
+ else if (container->focus_child == xpaned->bottom_right_child)
+ gtk_xpaned_set_last_bottom_right_child_focus (xpaned, last_focus);
+ }
+ }
+
+ if (parent_class->set_focus_child)
+ (* parent_class->set_focus_child) (container, focus_child);
+}
+
+static void gtk_xpaned_get_cycle_chain (GtkXPaned* xpaned,
+ GtkDirectionType direction,
+ GList** widgets)
+{
+ GtkContainer* container = GTK_CONTAINER (xpaned);
+ GtkWidget* ancestor = NULL;
+ GList* temp_list = NULL;
+ GList* list;
+
+ if (xpaned->in_recursion)
+ return;
+
+ g_assert (widgets != NULL);
+
+ if (xpaned->last_top_left_child_focus &&
+ !gtk_widget_is_ancestor (xpaned->last_top_left_child_focus,
+ GTK_WIDGET (xpaned)))
+ {
+ gtk_xpaned_set_last_top_left_child_focus (xpaned, NULL);
+ }
+
+ if (xpaned->last_top_right_child_focus &&
+ !gtk_widget_is_ancestor (xpaned->last_top_right_child_focus,
+ GTK_WIDGET (xpaned)))
+ {
+ gtk_xpaned_set_last_top_right_child_focus (xpaned, NULL);
+ }
+
+ if (xpaned->last_bottom_left_child_focus &&
+ !gtk_widget_is_ancestor (xpaned->last_bottom_left_child_focus,
+ GTK_WIDGET (xpaned)))
+ {
+ gtk_xpaned_set_last_bottom_left_child_focus (xpaned, NULL);
+ }
+
+ if (xpaned->last_bottom_right_child_focus &&
+ !gtk_widget_is_ancestor (xpaned->last_bottom_right_child_focus,
+ GTK_WIDGET (xpaned)))
+ {
+ gtk_xpaned_set_last_bottom_right_child_focus (xpaned, NULL);
+ }
+
+ if (GTK_WIDGET (xpaned)->parent)
+ ancestor = gtk_widget_get_ancestor (GTK_WIDGET (xpaned)->parent,
+ GTK_TYPE_XPANED);
+
+ /* The idea here is that temp_list is a list of widgets we want to cycle
+ * to. The list is prioritized so that the first element is our first
+ * choice, the next our second, and so on.
+ *
+ * We can't just use g_list_reverse(), because we want to try
+ * paned->last_child?_focus before paned->child?, both when we
+ * are going forward and backward.
+ */
+ if (direction == GTK_DIR_TAB_FORWARD)
+ {
+ if (container->focus_child == xpaned->top_left_child)
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_right_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ else if (container->focus_child == xpaned->top_right_child)
+ {
+ temp_list = g_list_append (temp_list, ancestor);
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ }
+ else if (container->focus_child == xpaned->bottom_left_child)
+ {
+ temp_list = g_list_append (temp_list, ancestor);
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_right_child);
+ }
+ else if (container->focus_child == xpaned->bottom_right_child)
+ {
+ temp_list = g_list_append (temp_list, ancestor);
+ temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_left_child);
+ }
+ else
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_left_child);
+ temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_right_child);
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_right_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ }
+ else
+ {
+ if (container->focus_child == xpaned->top_left_child)
+ {
+ temp_list = g_list_append (temp_list, ancestor);
+ temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_right_child);
+ }
+ else if (container->focus_child == xpaned->top_right_child)
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ else if (container->focus_child == xpaned->bottom_right_child)
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ else if (container->focus_child == xpaned->top_right_child)
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ else
+ {
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_right_child);
+ temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->bottom_left_child);
+ temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_right_child);
+ temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus);
+ temp_list = g_list_append (temp_list, xpaned->top_left_child);
+ temp_list = g_list_append (temp_list, ancestor);
+ }
+ }
+
+ /* Walk the list and expand all the paned widgets. */
+ for (list = temp_list; list != NULL; list = list->next)
+ {
+ GtkWidget *widget = list->data;
+
+ if (widget)
+ {
+ if (GTK_IS_XPANED (widget))
+ {
+ xpaned->in_recursion = TRUE;
+ gtk_xpaned_get_cycle_chain (GTK_XPANED (widget),
+ direction,
+ widgets);
+ xpaned->in_recursion = FALSE;
+ }
+ else
+ {
+ *widgets = g_list_append (*widgets, widget);
+ }
+ }
+ }
+
+ g_list_free (temp_list);
+}
+
+static gboolean gtk_xpaned_cycle_child_focus (GtkXPaned* xpaned,
+ gboolean reversed)
+{
+ GList* cycle_chain = NULL;
+ GList* list;
+
+ GtkDirectionType direction = reversed ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD;
+
+ /* ignore f6 if the handle is focused */
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ return TRUE;
+
+ /* we can't just let the event propagate up the hierarchy,
+ * because the paned will want to cycle focus _unless_ an
+ * ancestor paned handles the event
+ */
+ gtk_xpaned_get_cycle_chain (xpaned, direction, &cycle_chain);
+
+ for (list = cycle_chain; list != NULL; list = list->next)
+ if (gtk_widget_child_focus (GTK_WIDGET (list->data), direction))
+ break;
+
+ g_list_free (cycle_chain);
+
+ return TRUE;
+}
+
+static void get_child_xpanes (GtkWidget* widget, GList** xpanes)
+{
+ if (GTK_IS_XPANED (widget))
+ {
+ GtkXPaned* xpaned = GTK_XPANED (widget);
+
+ get_child_xpanes (xpaned->top_left_child, xpanes);
+ *xpanes = g_list_prepend (*xpanes, widget);
+ get_child_xpanes (xpaned->top_right_child, xpanes);
+ *xpanes = g_list_prepend (*xpanes, widget);
+ get_child_xpanes (xpaned->bottom_left_child, xpanes);
+ *xpanes = g_list_prepend (*xpanes, widget);
+ get_child_xpanes (xpaned->bottom_right_child, xpanes);
+ }
+ else if (GTK_IS_CONTAINER (widget))
+ {
+ gtk_container_foreach (GTK_CONTAINER (widget),
+ (GtkCallback)get_child_xpanes,
+ xpanes);
+ }
+}
+
+static GList* get_all_xpanes (GtkXPaned* xpaned)
+{
+ GtkXPaned* topmost = NULL;
+ GList* result = NULL;
+ GtkWidget* w;
+
+ for (w = GTK_WIDGET (xpaned); w != NULL; w = w->parent)
+ {
+ if (GTK_IS_XPANED (w))
+ topmost = GTK_XPANED (w);
+ }
+
+ g_assert (topmost);
+
+ get_child_xpanes (GTK_WIDGET (topmost), &result);
+
+ return g_list_reverse (result);
+}
+
+static void gtk_xpaned_find_neighbours (GtkXPaned* xpaned,
+ GtkXPaned** next,
+ GtkXPaned** prev)
+{
+ GList* all_xpanes;
+ GList* this_link;
+
+ all_xpanes = get_all_xpanes (xpaned);
+ g_assert (all_xpanes);
+
+ this_link = g_list_find (all_xpanes, xpaned);
+
+ g_assert (this_link);
+
+ if (this_link->next)
+ *next = this_link->next->data;
+ else
+ *next = all_xpanes->data;
+
+ if (this_link->prev)
+ *prev = this_link->prev->data;
+ else
+ *prev = g_list_last (all_xpanes)->data;
+
+ g_list_free (all_xpanes);
+}
+
+static gboolean gtk_xpaned_move_handle (GtkXPaned* xpaned, GtkScrollType scroll)
+{
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ GdkPoint old_position;
+ GdkPoint new_position;
+ gint increment;
+
+ enum
+ {
+ SINGLE_STEP_SIZE = 1,
+ PAGE_STEP_SIZE = 75
+ };
+
+ new_position.x = old_position.x = gtk_xpaned_get_position_x (xpaned);
+ new_position.y = old_position.y = gtk_xpaned_get_position_y (xpaned);
+ increment = 0;
+
+ switch (scroll)
+ {
+ case GTK_SCROLL_STEP_LEFT:
+ case GTK_SCROLL_STEP_UP:
+ case GTK_SCROLL_STEP_BACKWARD:
+ increment = - SINGLE_STEP_SIZE;
+ break;
+
+ case GTK_SCROLL_STEP_RIGHT:
+ case GTK_SCROLL_STEP_DOWN:
+ case GTK_SCROLL_STEP_FORWARD:
+ increment = SINGLE_STEP_SIZE;
+ break;
+
+ case GTK_SCROLL_PAGE_LEFT:
+ case GTK_SCROLL_PAGE_UP:
+ case GTK_SCROLL_PAGE_BACKWARD:
+ increment = - PAGE_STEP_SIZE;
+ break;
+
+ case GTK_SCROLL_PAGE_RIGHT:
+ case GTK_SCROLL_PAGE_DOWN:
+ case GTK_SCROLL_PAGE_FORWARD:
+ increment = PAGE_STEP_SIZE;
+ break;
+
+ case GTK_SCROLL_START:
+ new_position.x = xpaned->min_position.x;
+ new_position.y = xpaned->min_position.y;
+ break;
+
+ case GTK_SCROLL_END:
+ new_position.x = xpaned->max_position.x;
+ new_position.y = xpaned->max_position.y;
+ break;
+
+ default:
+ break;
+ }
+
+ if (increment)
+ {
+ if (is_rtl (xpaned))
+ increment = -increment;
+
+ new_position.x = old_position.x + increment;
+ new_position.y = old_position.y + increment;
+ }
+
+ new_position.x = CLAMP (new_position.x,
+ xpaned->min_position.x,
+ xpaned->max_position.x);
+
+ new_position.y = CLAMP (new_position.y,
+ xpaned->min_position.y,
+ xpaned->max_position.y);
+
+ if (old_position.x != new_position.x)
+ gtk_xpaned_set_position_x (xpaned, new_position.x);
+
+ if (old_position.y != new_position.y)
+ gtk_xpaned_set_position_y (xpaned, new_position.y);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void gtk_xpaned_restore_focus (GtkXPaned* xpaned)
+{
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ if (xpaned->priv->saved_focus &&
+ GTK_WIDGET_SENSITIVE (xpaned->priv->saved_focus))
+ {
+ gtk_widget_grab_focus (xpaned->priv->saved_focus);
+ }
+ else
+ {
+ /* the saved focus is somehow not available for focusing,
+ * try
+ * 1) tabbing into the paned widget
+ * if that didn't work,
+ * 2) unset focus for the window if there is one
+ */
+
+ if (!gtk_widget_child_focus (GTK_WIDGET (xpaned), GTK_DIR_TAB_FORWARD))
+ {
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned));
+
+ if (GTK_IS_WINDOW (toplevel))
+ gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
+ }
+ }
+
+ gtk_xpaned_set_saved_focus (xpaned, NULL);
+ gtk_xpaned_set_first_xpaned (xpaned, NULL);
+ }
+}
+
+static gboolean gtk_xpaned_accept_position (GtkXPaned* xpaned)
+{
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ xpaned->original_position.x = -1;
+ xpaned->original_position.y = -1;
+ gtk_xpaned_restore_focus (xpaned);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean gtk_xpaned_cancel_position (GtkXPaned* xpaned)
+{
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ if (xpaned->original_position.x != -1)
+ {
+ gtk_xpaned_set_position_x (xpaned, xpaned->original_position.x);
+ xpaned->original_position.x = -1;
+ }
+
+ if (xpaned->original_position.y != -1)
+ {
+ gtk_xpaned_set_position_y (xpaned, xpaned->original_position.y);
+ xpaned->original_position.y = -1;
+ }
+
+ gtk_xpaned_restore_focus (xpaned);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean gtk_xpaned_cycle_handle_focus (GtkXPaned* xpaned,
+ gboolean reversed)
+{
+ GtkXPaned* next;
+ GtkXPaned* prev;
+
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ GtkXPaned* focus = NULL;
+
+ if (!xpaned->priv->first_xpaned)
+ {
+ /* The first_pane has disappeared. As an ad-hoc solution,
+ * we make the currently focused paned the first_paned. To the
+ * user this will seem like the paned cycling has been reset.
+ */
+ gtk_xpaned_set_first_xpaned (xpaned, xpaned);
+ }
+
+ gtk_xpaned_find_neighbours (xpaned, &next, &prev);
+
+ if (reversed && prev &&
+ prev != xpaned && xpaned != xpaned->priv->first_xpaned)
+ {
+ focus = prev;
+ }
+ else if (!reversed &&
+ next &&
+ next != xpaned &&
+ next != xpaned->priv->first_xpaned)
+ {
+ focus = next;
+ }
+ else
+ {
+ gtk_xpaned_accept_position (xpaned);
+ return TRUE;
+ }
+
+ g_assert (focus);
+
+ gtk_xpaned_set_saved_focus (focus, xpaned->priv->saved_focus);
+ gtk_xpaned_set_first_xpaned (focus, xpaned->priv->first_xpaned);
+
+ gtk_xpaned_set_saved_focus (xpaned, NULL);
+ gtk_xpaned_set_first_xpaned (xpaned, NULL);
+
+ gtk_widget_grab_focus (GTK_WIDGET (focus));
+
+ if (!gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ {
+ xpaned->original_position.x = -1;
+ xpaned->original_position.y = -1;
+ focus->original_position.x = gtk_xpaned_get_position_x (focus);
+ focus->original_position.y = gtk_xpaned_get_position_y (focus);
+ }
+ }
+ else
+ {
+ GtkContainer* container = GTK_CONTAINER (xpaned);
+ GtkXPaned* focus;
+ GtkXPaned* first;
+ GtkXPaned* prev;
+ GtkXPaned* next;
+ GtkWidget* toplevel;
+
+ gtk_xpaned_find_neighbours (xpaned, &next, &prev);
+
+ if (container->focus_child == xpaned->top_left_child)
+ {
+ if (reversed)
+ {
+ focus = prev;
+ first = xpaned;
+ }
+ else
+ {
+ focus = xpaned;
+ first = xpaned;
+ }
+ }
+ else if (container->focus_child == xpaned->top_right_child)
+ {
+ if (reversed)
+ {
+ focus = xpaned;
+ first = next;
+ }
+ else
+ {
+ focus = next;
+ first = next;
+ }
+ }
+ else
+ {
+ /* Focus is not inside this xpaned, and we don't have focus.
+ * Presumably this happened because the application wants us
+ * to start keyboard navigating.
+ */
+ focus = xpaned;
+
+ if (reversed)
+ first = xpaned;
+ else
+ first = next;
+ }
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned));
+
+ if (GTK_IS_WINDOW (toplevel))
+ gtk_xpaned_set_saved_focus (focus, GTK_WINDOW (toplevel)->focus_widget);
+ gtk_xpaned_set_first_xpaned (focus, first);
+ focus->original_position.x = gtk_xpaned_get_position_x (focus);
+ focus->original_position.y = gtk_xpaned_get_position_y (focus);
+
+ gtk_widget_grab_focus (GTK_WIDGET (focus));
+ }
+
+ return TRUE;
+}
+
+static gboolean gtk_xpaned_toggle_handle_focus (GtkXPaned* xpaned)
+{
+ /* This function/signal has the wrong name. It is called when you
+ * press Tab or Shift-Tab and what we do is act as if
+ * the user pressed Return and then Tab or Shift-Tab
+ */
+ if (gtk_widget_is_focus (GTK_WIDGET (xpaned)))
+ gtk_xpaned_accept_position (xpaned);
+
+ return FALSE;
+}
+
+/*#define __GTK_XPANED_C__*/
+/*#include "gtkaliasdef.c"*/
--- /dev/null
+/*******************************************************************************
+**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+** 10 20 30 40 50 60 70 80
+**
+** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+
+** Copyright (C) 2005-2006 Mirco "MacSlow" Müller <macslow@bangang.de>
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** GtkXPaned is based on GtkPaned which was done by...
+**
+** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald"
+**
+** and later modified by...
+**
+** "the GTK+ Team and others 1997-2000"
+**
+*******************************************************************************/
+
+#ifndef GTK_XPANED_H
+#define GTK_XPANED_H
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_XPANED (gtk_xpaned_get_type ())
+#define GTK_XPANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_XPANED, GtkXPaned))
+#define GTK_XPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_XPANED, GtkXPanedClass))
+#define GTK_IS_XPANED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_XPANED))
+#define GTK_IS_XPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XPANED))
+#define GTK_XPANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XPANED, GtkXPanedClass))
+
+typedef struct _GtkXPaned GtkXPaned;
+typedef struct _GtkXPanedClass GtkXPanedClass;
+typedef struct _GtkXPanedPrivate GtkXPanedPrivate;
+
+typedef enum _GtkXPanedChild
+{
+ GTK_XPANED_TOP_LEFT = 0,
+ GTK_XPANED_TOP_RIGHT,
+ GTK_XPANED_BOTTOM_LEFT,
+ GTK_XPANED_BOTTOM_RIGHT
+} GtkXPanedChild;
+
+struct _GtkXPaned
+{
+ GtkContainer container;
+
+ GtkWidget* top_left_child;
+ GtkWidget* top_right_child;
+ GtkWidget* bottom_left_child;
+ GtkWidget* bottom_right_child;
+
+ GdkWindow* handle_east;
+ GdkWindow* handle_west;
+ GdkWindow* handle_north;
+ GdkWindow* handle_south;
+ GdkWindow* handle_middle;
+ GdkGC* xor_gc;
+ GdkCursorType cursor_type_east;
+ GdkCursorType cursor_type_west;
+ GdkCursorType cursor_type_north;
+ GdkCursorType cursor_type_south;
+ GdkCursorType cursor_type_middle;
+
+ /*< private >*/
+ GdkRectangle handle_pos_east;
+ GdkRectangle handle_pos_west;
+ GdkRectangle handle_pos_north;
+ GdkRectangle handle_pos_south;
+ GdkRectangle handle_pos_middle;
+ GtkRequisition top_left_child_size;
+ GtkRequisition top_right_child_size;
+ GtkRequisition bottom_left_child_size;
+ GtkRequisition bottom_right_child_size;
+
+ GtkRequisition last_allocation;
+ GdkPoint min_position;
+ GdkPoint max_position;
+ gboolean maximized[4];
+
+ guint position_set : 1;
+ guint in_drag_vert : 1;
+ guint in_drag_horiz : 1;
+ guint in_drag_vert_and_horiz : 1;
+ guint top_left_child_shrink : 1;
+ guint top_left_child_resize : 1;
+ guint top_right_child_shrink : 1;
+ guint top_right_child_resize : 1;
+ guint bottom_left_child_shrink : 1;
+ guint bottom_left_child_resize : 1;
+ guint bottom_right_child_shrink : 1;
+ guint bottom_right_child_resize : 1;
+ guint in_recursion : 1;
+ guint handle_prelit : 1;
+
+ GtkWidget* last_top_left_child_focus;
+ GtkWidget* last_top_right_child_focus;
+ GtkWidget* last_bottom_left_child_focus;
+ GtkWidget* last_bottom_right_child_focus;
+ GtkXPanedPrivate* priv;
+
+ GdkPoint drag_pos;
+ GdkPoint original_position;
+ GdkPoint unmaximized_position;
+};
+
+struct _GtkXPanedClass
+{
+ GtkContainerClass parent_class;
+ gboolean (*cycle_child_focus) (GtkXPaned* xpaned, gboolean reverse);
+ gboolean (*toggle_handle_focus) (GtkXPaned* xpaned);
+ gboolean (*move_handle) (GtkXPaned* xpaned, GtkScrollType scroll);
+ gboolean (*cycle_handle_focus) (GtkXPaned* xpaned, gboolean reverse);
+ gboolean (*accept_position) (GtkXPaned* xpaned);
+ gboolean (*cancel_position) (GtkXPaned* xpaned);
+};
+
+GType gtk_xpaned_get_type (void) G_GNUC_CONST;
+GtkWidget* gtk_xpaned_new (void);
+void gtk_xpaned_add_top_left (GtkXPaned* xpaned, GtkWidget* child);
+void gtk_xpaned_add_top_right (GtkXPaned* xpaned, GtkWidget* child);
+void gtk_xpaned_add_bottom_left (GtkXPaned* xpaned, GtkWidget* child);
+void gtk_xpaned_add_bottom_right (GtkXPaned* xpaned, GtkWidget* child);
+void gtk_xpaned_pack_top_left (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink);
+void gtk_xpaned_pack_top_right (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink);
+void gtk_xpaned_pack_bottom_left (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink);
+void gtk_xpaned_pack_bottom_right (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink);
+gint gtk_xpaned_get_position_x (GtkXPaned* xpaned);
+gint gtk_xpaned_get_position_y (GtkXPaned* xpaned);
+void gtk_xpaned_set_position_x (GtkXPaned* xpaned, gint xposition);
+void gtk_xpaned_set_position_y (GtkXPaned* xpaned, gint yposition);
+void gtk_xpaned_save_unmaximized_x (GtkXPaned* xpaned);
+void gtk_xpaned_save_unmaximized_y (GtkXPaned* xpaned);
+gint gtk_xpaned_fetch_unmaximized_x (GtkXPaned* xpaned);
+gint gtk_xpaned_fetch_unmaximized_y (GtkXPaned* xpaned);
+GtkWidget* gtk_xpaned_get_top_left_child (GtkXPaned* xpaned);
+GtkWidget* gtk_xpaned_get_top_right_child (GtkXPaned* xpaned);
+GtkWidget* gtk_xpaned_get_bottom_right_child (GtkXPaned* xpaned);
+GtkWidget* gtk_xpaned_get_bottom_left_child (GtkXPaned* xpaned);
+gboolean gtk_xpaned_maximize_top_left (GtkXPaned* xpaned, gboolean maximize);
+gboolean gtk_xpaned_maximize_top_right (GtkXPaned* xpaned, gboolean maximize);
+gboolean gtk_xpaned_maximize_bottom_left (GtkXPaned* xpaned, gboolean maximize);
+gboolean gtk_xpaned_maximize_bottom_right (GtkXPaned* xpaned, gboolean maximize);
+
+/* Internal function */
+#if !defined (GTK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION)
+void gtk_xpaned_compute_position (GtkXPaned* xpaned,
+ const GtkAllocation* allocation,
+ GtkRequisition* top_left_child_req,
+ GtkRequisition* top_right_child_req,
+ GtkRequisition* bottom_left_child_req,
+ GtkRequisition* bottom_right_child_req);
+#endif /* !GTK_DISABLE_DEPRECATED || GTK_COMPILATION */
+#ifndef GTK_DISABLE_DEPRECATED
+#define gtk_xpaned_gutter_size(p,s) (void) 0
+#define gtk_xpaned_set_gutter_size(p,s) (void) 0
+#endif /* GTK_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* GTK_XPANED_H */
--- /dev/null
+#List of custom marshallers used by psppire
+
+BOOLEAN:BOOLEAN
+BOOLEAN:ENUM
+BOOLEAN:BOXED,POINTER
+BOOLEAN:VOID
+VOID:BOXED,BOXED
+VOID:INT,INT
+VOID:INT,LONG
+VOID:INT,INT,INT
+VOID:INT,INT,INT,INT
+VOID:INT,POINTER
+VOID:OBJECT,OBJECT
--- /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;
+
+ g_return_if_fail (n_units > 0);
+
+ 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 < tower_height (&a->unit_tower));
+ g_return_if_fail ( posn >= 0);
+
+ new_node = pool_malloc (a->pool, sizeof (*new_node));
+
+ if ( posn > 0)
+ {
+ 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);
+ }
+
+ 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;
+ g_return_if_fail (first + n_units < tower_height (&a->unit_tower));
+
+ split (a, first);
+ split (a, first + n_units);
+
+ struct tower_node *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 <lib/gtksheet/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__ */
msgstr ""
"Project-Id-Version: PSPP 0.7.0\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2008-11-08 12:59+0900\n"
+"POT-Creation-Date: 2008-11-11 13:13+0900\n"
"PO-Revision-Date: 2008-11-05 08:17+0900\n"
"Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
"Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
msgstr ""
#: src/data/format.c:327 src/data/sys-file-reader.c:655
-#: src/ui/gui/data-editor.glade:1190 src/ui/gui/psppire.glade:2176
+#: src/ui/gui/data-editor.glade:1197 src/ui/gui/psppire.glade:2176
#: src/ui/gui/psppire-var-store.c:605
msgid "String"
msgstr ""
#: src/data/format.c:327 src/data/sys-file-reader.c:655
-#: src/ui/gui/data-editor.glade:1079 src/ui/gui/psppire.glade:2131
+#: src/ui/gui/data-editor.glade:1086 src/ui/gui/psppire.glade:2131
#: src/ui/gui/psppire-var-store.c:598
msgid "Numeric"
msgstr ""
msgid "Cum"
msgstr ""
-#: src/language/stats/frequencies.q:1056 src/output/charts/plot-hist.c:138
+#: src/language/stats/frequencies.q:1056 src/output/charts/plot-hist.c:140
msgid "Frequency"
msgstr ""
msgid "Only USE ALL is currently implemented."
msgstr ""
-#: src/language/utilities/include.c:91
+#: src/language/utilities/include.c:90
msgid "Expecting BATCH or INTERACTIVE after SYNTAX."
msgstr ""
-#: src/language/utilities/include.c:108
+#: src/language/utilities/include.c:107
msgid "Expecting YES or NO after CD."
msgstr ""
-#: src/language/utilities/include.c:125
+#: src/language/utilities/include.c:124
msgid "Expecting CONTINUE or STOP after ERROR."
msgstr ""
-#: src/language/utilities/include.c:132
+#: src/language/utilities/include.c:131
#, c-format
msgid "Unexpected token: `%s'."
msgstr ""
-#: src/language/utilities/include.c:177
+#: src/language/utilities/include.c:176
msgid "expecting file name"
msgstr ""
-#: src/language/utilities/include.c:189
+#: src/language/utilities/include.c:188
#, c-format
msgid "Can't find `%s' in include file search path."
msgstr ""
msgid "creating \"%s\""
msgstr ""
-#: src/output/charts/plot-hist.c:136
+#: src/output/charts/plot-hist.c:138
msgid "HISTOGRAM"
msgstr ""
msgid "Style of bevel around the custom entry button"
msgstr ""
-#: src/ui/gui/data-editor.c:150
+#: src/ui/gui/data-editor.c:152
msgid "Transformations Pending"
msgstr ""
-#: src/ui/gui/data-editor.c:323
+#: src/ui/gui/data-editor.c:325
msgid "_Labels"
msgstr ""
-#: src/ui/gui/data-editor.c:324
+#: src/ui/gui/data-editor.c:326
msgid "Show/hide value labels"
msgstr ""
-#: src/ui/gui/data-editor.c:342 src/ui/gui/data-editor.c:361
-#: src/ui/gui/data-editor.c:1512 src/ui/gui/data-editor.c:1566
+#: src/ui/gui/data-editor.c:344 src/ui/gui/data-editor.c:363
+#: src/ui/gui/data-editor.c:1539 src/ui/gui/data-editor.c:1593
msgid "Clear"
msgstr ""
-#: src/ui/gui/data-editor.c:343
+#: src/ui/gui/data-editor.c:345
msgid "Delete the cases at the selected position(s)"
msgstr ""
-#: src/ui/gui/data-editor.c:362
+#: src/ui/gui/data-editor.c:364
msgid "Delete the variables at the selected position(s)"
msgstr ""
-#: src/ui/gui/data-editor.c:377
+#: src/ui/gui/data-editor.c:379
msgid "Insert _Variable"
msgstr ""
-#: src/ui/gui/data-editor.c:378
+#: src/ui/gui/data-editor.c:380
msgid "Create a new variable at the current position"
msgstr ""
-#: src/ui/gui/data-editor.c:396
+#: src/ui/gui/data-editor.c:398
msgid "Insert Ca_se"
msgstr ""
-#: src/ui/gui/data-editor.c:397
+#: src/ui/gui/data-editor.c:399
msgid "Create a new case at the current position"
msgstr ""
-#: src/ui/gui/data-editor.c:417
+#: src/ui/gui/data-editor.c:419
msgid "_Goto Case"
msgstr ""
-#: src/ui/gui/data-editor.c:418
+#: src/ui/gui/data-editor.c:420
msgid "Jump to a Case in the Data Sheet"
msgstr ""
-#: src/ui/gui/data-editor.c:437
+#: src/ui/gui/data-editor.c:439
msgid "_Weights"
msgstr ""
-#: src/ui/gui/data-editor.c:438
+#: src/ui/gui/data-editor.c:440
msgid "Weight cases by variable"
msgstr ""
-#: src/ui/gui/data-editor.c:447 src/ui/gui/data-editor.glade:319
+#: src/ui/gui/data-editor.c:449 src/ui/gui/data-editor.glade:319
msgid "_Transpose"
msgstr ""
-#: src/ui/gui/data-editor.c:448
+#: src/ui/gui/data-editor.c:450
msgid "Transpose the cases with the variables"
msgstr ""
-#: src/ui/gui/data-editor.c:459
+#: src/ui/gui/data-editor.c:461
msgid "S_plit"
msgstr ""
-#: src/ui/gui/data-editor.c:460
+#: src/ui/gui/data-editor.c:462
msgid "Split the active file"
msgstr ""
-#: src/ui/gui/data-editor.c:470
+#: src/ui/gui/data-editor.c:472
msgid "_Sort"
msgstr ""
-#: src/ui/gui/data-editor.c:471
+#: src/ui/gui/data-editor.c:473
msgid "Sort cases in the active file"
msgstr ""
-#: src/ui/gui/data-editor.c:479 src/ui/gui/data-editor.glade:340
+#: src/ui/gui/data-editor.c:481 src/ui/gui/data-editor.glade:340
msgid "Select _Cases"
msgstr ""
-#: src/ui/gui/data-editor.c:480
+#: src/ui/gui/data-editor.c:482
msgid "Select cases from the active file"
msgstr ""
-#: src/ui/gui/data-editor.c:489 src/ui/gui/data-editor.glade:369
+#: src/ui/gui/data-editor.c:491 src/ui/gui/data-editor.glade:369
msgid "_Compute"
msgstr ""
-#: src/ui/gui/data-editor.c:490
+#: src/ui/gui/data-editor.c:492
msgid "Compute new values for a variable"
msgstr ""
-#: src/ui/gui/data-editor.c:498
+#: src/ui/gui/data-editor.c:500
msgid "Oneway _ANOVA"
msgstr ""
-#: src/ui/gui/data-editor.c:499
+#: src/ui/gui/data-editor.c:501
msgid "Perform one way analysis of variance"
msgstr ""
-#: src/ui/gui/data-editor.c:507 src/ui/gui/data-editor.glade:496
+#: src/ui/gui/data-editor.c:509 src/ui/gui/data-editor.glade:496
msgid "_Independent Samples T Test"
msgstr ""
-#: src/ui/gui/data-editor.c:508
+#: src/ui/gui/data-editor.c:510
msgid "Calculate T Test for samples from independent groups"
msgstr ""
-#: src/ui/gui/data-editor.c:517 src/ui/gui/data-editor.glade:504
+#: src/ui/gui/data-editor.c:519 src/ui/gui/data-editor.glade:504
msgid "_Paired Samples T Test"
msgstr ""
-#: src/ui/gui/data-editor.c:518
+#: src/ui/gui/data-editor.c:520
msgid "Calculate T Test for paired samples"
msgstr ""
-#: src/ui/gui/data-editor.c:527
+#: src/ui/gui/data-editor.c:529
msgid "One _Sample T Test"
msgstr ""
-#: src/ui/gui/data-editor.c:528
+#: src/ui/gui/data-editor.c:530
msgid "Calculate T Test for sample from a single distribution"
msgstr ""
-#: src/ui/gui/data-editor.c:537 src/ui/gui/data-editor.glade:593
+#: src/ui/gui/data-editor.c:539 src/ui/gui/data-editor.glade:593
msgid "Data File _Comments"
msgstr ""
-#: src/ui/gui/data-editor.c:538
+#: src/ui/gui/data-editor.c:540
msgid "Commentary text for the data file"
msgstr ""
-#: src/ui/gui/data-editor.c:546 src/ui/gui/data-editor.glade:228
+#: src/ui/gui/data-editor.c:548 src/ui/gui/data-editor.glade:228
msgid "_Find"
msgstr ""
-#: src/ui/gui/data-editor.c:547
+#: src/ui/gui/data-editor.c:549
msgid "Find Case"
msgstr ""
-#: src/ui/gui/data-editor.c:556 src/ui/gui/data-editor.glade:377
+#: src/ui/gui/data-editor.c:558 src/ui/gui/data-editor.glade:377
msgid "Ran_k Cases"
msgstr ""
-#: src/ui/gui/data-editor.c:557
+#: src/ui/gui/data-editor.c:559
msgid "Rank Cases"
msgstr ""
-#: src/ui/gui/data-editor.c:566 src/ui/gui/data-editor.glade:389
+#: src/ui/gui/data-editor.c:568 src/ui/gui/data-editor.glade:389
msgid "Recode into _Same Variables"
msgstr ""
-#: src/ui/gui/data-editor.c:567
+#: src/ui/gui/data-editor.c:569
msgid "Recode values into the same Variables"
msgstr ""
-#: src/ui/gui/data-editor.c:576 src/ui/gui/data-editor.glade:396
+#: src/ui/gui/data-editor.c:578 src/ui/gui/data-editor.glade:396
msgid "Recode into _Different Variables"
msgstr ""
-#: src/ui/gui/data-editor.c:577
+#: src/ui/gui/data-editor.c:579
msgid "Recode values into different Variables"
msgstr ""
-#: src/ui/gui/data-editor.c:586 src/ui/gui/data-editor.glade:293
+#: src/ui/gui/data-editor.c:588 src/ui/gui/data-editor.glade:293
#: src/ui/gui/data-editor.glade:584
msgid "_Variables"
msgstr ""
-#: src/ui/gui/data-editor.c:587
+#: src/ui/gui/data-editor.c:589
msgid "Jump to Variable"
msgstr ""
-#: src/ui/gui/data-editor.c:595 src/ui/gui/data-editor.glade:450
+#: src/ui/gui/data-editor.c:597 src/ui/gui/data-editor.glade:450
#: src/ui/gui/oneway.glade:179
msgid "_Descriptives"
msgstr ""
-#: src/ui/gui/data-editor.c:596
+#: src/ui/gui/data-editor.c:598
msgid "Calculate descriptive statistics (mean, variance, ...)"
msgstr ""
-#: src/ui/gui/data-editor.c:605 src/ui/gui/data-editor.glade:442
+#: src/ui/gui/data-editor.c:607 src/ui/gui/data-editor.glade:442
msgid "_Frequencies"
msgstr ""
-#: src/ui/gui/data-editor.c:606
+#: src/ui/gui/data-editor.c:608
msgid "Generate frequency statistics"
msgstr ""
-#: src/ui/gui/data-editor.c:614 src/ui/gui/data-editor.glade:466
+#: src/ui/gui/data-editor.c:616 src/ui/gui/data-editor.glade:466
msgid "_Crosstabs"
msgstr ""
-#: src/ui/gui/data-editor.c:615
+#: src/ui/gui/data-editor.c:617
msgid "Generate crosstabulations"
msgstr ""
-#: src/ui/gui/data-editor.c:624 src/ui/gui/data-editor.glade:458
+#: src/ui/gui/data-editor.c:626 src/ui/gui/data-editor.glade:458
msgid "_Explore"
msgstr ""
-#: src/ui/gui/data-editor.c:625
+#: src/ui/gui/data-editor.c:627
msgid "Examine Data by Factors"
msgstr ""
-#: src/ui/gui/data-editor.c:634 src/ui/gui/data-editor.glade:532
+#: src/ui/gui/data-editor.c:636 src/ui/gui/data-editor.glade:532
msgid "Linear _Regression"
msgstr ""
-#: src/ui/gui/data-editor.c:635
+#: src/ui/gui/data-editor.c:637
msgid "Estimate parameters of the linear model"
msgstr ""
-#: src/ui/gui/data-editor.c:1027
+#: src/ui/gui/data-editor.c:921
+msgid "_Split Window"
+msgstr ""
+
+#: src/ui/gui/data-editor.c:922
+msgid "Split the window vertically and horizontally"
+msgstr ""
+
+#: src/ui/gui/data-editor.c:1042
msgid "Font Selection"
msgstr ""
-#: src/ui/gui/data-editor.c:1099
+#: src/ui/gui/data-editor.c:1126
msgid "No Split"
msgstr ""
-#: src/ui/gui/data-editor.c:1108
+#: src/ui/gui/data-editor.c:1135
msgid "Split by "
msgstr ""
-#: src/ui/gui/data-editor.c:1133
+#: src/ui/gui/data-editor.c:1160
msgid "Filter off"
msgstr ""
-#: src/ui/gui/data-editor.c:1145
+#: src/ui/gui/data-editor.c:1172
#, c-format
msgid "Filter by %s"
msgstr ""
-#: src/ui/gui/data-editor.c:1163
+#: src/ui/gui/data-editor.c:1190
msgid "Weights off"
msgstr ""
-#: src/ui/gui/data-editor.c:1175
+#: src/ui/gui/data-editor.c:1202
#, c-format
msgid "Weight by %s"
msgstr ""
-#: src/ui/gui/data-editor.c:1198 src/ui/gui/data-editor.c:1445
-#: src/ui/gui/data-editor.glade:660
+#: src/ui/gui/data-editor.c:1225 src/ui/gui/data-editor.c:1472
+#: src/ui/gui/data-editor.glade:667
msgid "Open"
msgstr ""
-#: src/ui/gui/data-editor.c:1199
+#: src/ui/gui/data-editor.c:1226
msgid "Open a data file"
msgstr ""
-#: src/ui/gui/data-editor.c:1207 src/ui/gui/data-editor.c:1323
-#: src/ui/gui/data-editor.glade:670
+#: src/ui/gui/data-editor.c:1234 src/ui/gui/data-editor.c:1350
+#: src/ui/gui/data-editor.glade:677
msgid "Save"
msgstr ""
-#: src/ui/gui/data-editor.c:1208 src/ui/gui/data-editor.c:1218
+#: src/ui/gui/data-editor.c:1235 src/ui/gui/data-editor.c:1245
msgid "Save data to file"
msgstr ""
-#: src/ui/gui/data-editor.c:1217
+#: src/ui/gui/data-editor.c:1244
msgid "Save As"
msgstr ""
-#: src/ui/gui/data-editor.c:1226 src/ui/gui/recode-dialog.c:928
+#: src/ui/gui/data-editor.c:1253 src/ui/gui/recode-dialog.c:928
#: src/ui/gui/recode-dialog.c:1023
msgid "New"
msgstr ""
-#: src/ui/gui/data-editor.c:1227
+#: src/ui/gui/data-editor.c:1254
msgid "New data file"
msgstr ""
-#: src/ui/gui/data-editor.c:1235
+#: src/ui/gui/data-editor.c:1262
msgid "_Import Text Data"
msgstr ""
-#: src/ui/gui/data-editor.c:1236
+#: src/ui/gui/data-editor.c:1263
msgid "Import text data file"
msgstr ""
-#: src/ui/gui/data-editor.c:1331 src/ui/gui/data-editor.c:1453
+#: src/ui/gui/data-editor.c:1358 src/ui/gui/data-editor.c:1480
msgid "System Files (*.sav)"
msgstr ""
-#: src/ui/gui/data-editor.c:1337 src/ui/gui/data-editor.c:1459
+#: src/ui/gui/data-editor.c:1364 src/ui/gui/data-editor.c:1486
msgid "Portable Files (*.por) "
msgstr ""
-#: src/ui/gui/data-editor.c:1343 src/ui/gui/data-editor.c:1465
+#: src/ui/gui/data-editor.c:1370 src/ui/gui/data-editor.c:1492
#: src/ui/gui/syntax-editor.c:138 src/ui/gui/syntax-editor.c:522
msgid "All Files"
msgstr ""
-#: src/ui/gui/data-editor.c:1351
+#: src/ui/gui/data-editor.c:1378
msgid "System File"
msgstr ""
-#: src/ui/gui/data-editor.c:1356
+#: src/ui/gui/data-editor.c:1383
msgid "Portable File"
msgstr ""
-#: src/ui/gui/data-editor.c:1503
+#: src/ui/gui/data-editor.c:1530
msgid "Sort Ascending"
msgstr ""
-#: src/ui/gui/data-editor.c:1506
+#: src/ui/gui/data-editor.c:1533
msgid "Sort Descending"
msgstr ""
-#: src/ui/gui/data-editor.c:1509 src/ui/gui/data-editor.glade:150
-#: src/ui/gui/data-editor.glade:801
+#: src/ui/gui/data-editor.c:1536 src/ui/gui/data-editor.glade:150
+#: src/ui/gui/data-editor.glade:808
msgid "Insert Variable"
msgstr ""
-#: src/ui/gui/data-editor.c:1563 src/ui/gui/data-editor.glade:789
+#: src/ui/gui/data-editor.c:1590 src/ui/gui/data-editor.glade:796
msgid "Insert Case"
msgstr ""
msgid "Insert Cases"
msgstr ""
-#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:738
+#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:745
msgid "Go To Case"
msgstr ""
msgid "_Minimize All Windows"
msgstr "_Minimise All Windows"
-#: src/ui/gui/data-editor.glade:622 src/ui/gui/output-viewer.glade:99
+#: src/ui/gui/data-editor.glade:618
+msgid "_Split"
+msgstr ""
+
+#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:99
#: src/ui/gui/syntax-editor.glade:254
msgid "_Help"
msgstr ""
-#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:106
+#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:106
#: src/ui/gui/syntax-editor.glade:262
msgid "_Reference Manual"
msgstr ""
-#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:113
+#: src/ui/gui/data-editor.glade:643 src/ui/gui/output-viewer.glade:113
#: src/ui/gui/syntax-editor.glade:269
msgid "_About"
msgstr ""
-#: src/ui/gui/data-editor.glade:680
+#: src/ui/gui/data-editor.glade:687
msgid "Print"
msgstr ""
-#: src/ui/gui/data-editor.glade:690
+#: src/ui/gui/data-editor.glade:697
msgid "Recall"
msgstr ""
-#: src/ui/gui/data-editor.glade:708
+#: src/ui/gui/data-editor.glade:715
msgid "Undo"
msgstr ""
-#: src/ui/gui/data-editor.glade:718
+#: src/ui/gui/data-editor.glade:725
msgid "Redo"
msgstr ""
-#: src/ui/gui/data-editor.glade:748
+#: src/ui/gui/data-editor.glade:755
msgid "Variables"
msgstr ""
-#: src/ui/gui/data-editor.glade:769
+#: src/ui/gui/data-editor.glade:776
msgid "Find"
msgstr ""
-#: src/ui/gui/data-editor.glade:821
+#: src/ui/gui/data-editor.glade:828
msgid "Split File"
msgstr ""
-#: src/ui/gui/data-editor.glade:832
+#: src/ui/gui/data-editor.glade:839
msgid "Weight Cases"
msgstr ""
-#: src/ui/gui/data-editor.glade:844
+#: src/ui/gui/data-editor.glade:851
msgid "Select Cases"
msgstr ""
-#: src/ui/gui/data-editor.glade:864 src/ui/gui/data-editor.glade:1452
-#: src/ui/gui/data-editor.glade:1633
+#: src/ui/gui/data-editor.glade:871 src/ui/gui/data-editor.glade:1459
+#: src/ui/gui/data-editor.glade:1640
msgid "Value Labels"
msgstr ""
-#: src/ui/gui/data-editor.glade:875
+#: src/ui/gui/data-editor.glade:882
msgid "Use Sets"
msgstr ""
-#: src/ui/gui/data-editor.glade:907
+#: src/ui/gui/data-editor.glade:914
msgid "Information Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:926
+#: src/ui/gui/data-editor.glade:933
msgid "Processor Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:951
+#: src/ui/gui/data-editor.glade:958
msgid "Case Counter Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:976
+#: src/ui/gui/data-editor.glade:983
msgid "Filter Use Status Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:1002
+#: src/ui/gui/data-editor.glade:1009
msgid "Weight Status Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:1028
+#: src/ui/gui/data-editor.glade:1035
msgid "Split File Status Area"
msgstr ""
-#: src/ui/gui/data-editor.glade:1058
+#: src/ui/gui/data-editor.glade:1065
msgid "Variable Type"
msgstr ""
-#: src/ui/gui/data-editor.glade:1094 src/ui/gui/psppire-var-store.c:599
+#: src/ui/gui/data-editor.glade:1101 src/ui/gui/psppire-var-store.c:599
msgid "Comma"
msgstr ""
-#: src/ui/gui/data-editor.glade:1110 src/ui/gui/psppire-var-store.c:600
+#: src/ui/gui/data-editor.glade:1117 src/ui/gui/psppire-var-store.c:600
msgid "Dot"
msgstr ""
-#: src/ui/gui/data-editor.glade:1126
+#: src/ui/gui/data-editor.glade:1133
msgid "Scientific notation"
msgstr ""
-#: src/ui/gui/data-editor.glade:1142 src/ui/gui/psppire-var-store.c:602
+#: src/ui/gui/data-editor.glade:1149 src/ui/gui/psppire-var-store.c:602
msgid "Date"
msgstr ""
-#: src/ui/gui/data-editor.glade:1158 src/ui/gui/psppire-var-store.c:603
+#: src/ui/gui/data-editor.glade:1165 src/ui/gui/psppire-var-store.c:603
msgid "Dollar"
msgstr ""
-#: src/ui/gui/data-editor.glade:1174
+#: src/ui/gui/data-editor.glade:1181
msgid "Custom currency"
msgstr ""
-#: src/ui/gui/data-editor.glade:1268
+#: src/ui/gui/data-editor.glade:1275
msgid "positive"
msgstr ""
-#: src/ui/gui/data-editor.glade:1274
+#: src/ui/gui/data-editor.glade:1281
msgid "negative"
msgstr ""
-#: src/ui/gui/data-editor.glade:1287
+#: src/ui/gui/data-editor.glade:1294
msgid "Sample"
msgstr ""
-#: src/ui/gui/data-editor.glade:1337
+#: src/ui/gui/data-editor.glade:1344
msgid "Width:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1381
+#: src/ui/gui/data-editor.glade:1388
msgid "Decimal Places:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1550
+#: src/ui/gui/data-editor.glade:1557
msgid "Value Label:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1563 src/ui/gui/psppire.glade:2544
+#: src/ui/gui/data-editor.glade:1570 src/ui/gui/psppire.glade:2544
#: src/ui/gui/recode.glade:185
msgid "Value:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1700 src/ui/gui/examine.glade:423
+#: src/ui/gui/data-editor.glade:1707 src/ui/gui/examine.glade:423
#: src/ui/gui/t-test.glade:460
msgid "Missing Values"
msgstr ""
-#: src/ui/gui/data-editor.glade:1718
+#: src/ui/gui/data-editor.glade:1725
msgid "_Range plus one optional discrete missing value"
msgstr ""
-#: src/ui/gui/data-editor.glade:1743
+#: src/ui/gui/data-editor.glade:1750
msgid "_Low:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1772
+#: src/ui/gui/data-editor.glade:1779
msgid "_High:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1813
+#: src/ui/gui/data-editor.glade:1820
msgid "Di_screte value:"
msgstr ""
-#: src/ui/gui/data-editor.glade:1860
+#: src/ui/gui/data-editor.glade:1867
msgid "_No missing values"
msgstr ""
-#: src/ui/gui/data-editor.glade:1878
+#: src/ui/gui/data-editor.glade:1885
msgid "_Discrete missing values"
msgstr ""
msgid "Cannot open %s: %s.\n"
msgstr ""
-#: src/ui/gui/psppire-data-editor.c:604
+#: src/ui/gui/psppire.c:270
+#, c-format
+msgid "%s is neither a system nor portable file"
+msgstr ""
+
+#: src/ui/gui/psppire-data-editor.c:703
msgid "Data View"
msgstr ""
-#: src/ui/gui/psppire-data-editor.c:607
+#: src/ui/gui/psppire-data-editor.c:706
msgid "Variable View"
msgstr ""
-#: src/ui/gui/psppire-data-store.c:828
+#: src/ui/gui/psppire-data-store.c:829
msgid "var"
msgstr ""
for (node = tower_first (&old->log_to_phy); node != NULL;
node = tower_next (&old->log_to_phy, node))
{
- unsigned long int size = tower_node_get_height (node);
+ unsigned long int size = tower_node_get_size (node);
struct axis_group *group = tower_data (node, struct axis_group, logical);
tower_insert (&new->log_to_phy, size, make_axis_group (group->phy_start),
NULL);
{
struct axis_group *group = tower_data (tn, struct axis_group, logical);
unsigned long int phy_start = group->phy_start;
- unsigned long int size = tower_node_get_height (tn);
+ unsigned long int size = tower_node_get_size (tn);
md4_process_bytes (&phy_start, sizeof phy_start, ctx);
md4_process_bytes (&size, sizeof size, ctx);
if (where > group_start)
{
unsigned long int size_1 = where - group_start;
- unsigned long int size_2 = tower_node_get_height (group_node) - size_1;
+ unsigned long int size_2 = tower_node_get_size (group_node) - size_1;
struct tower_node *next = tower_next (&axis->log_to_phy, group_node);
struct tower_node *new = make_axis_group (group->phy_start + size_1);
tower_resize (&axis->log_to_phy, group_node, size_1);
if (next != NULL)
{
struct axis_group *next_group = axis_group_from_tower_node (next);
- unsigned long this_height = tower_node_get_height (node);
+ unsigned long this_height = tower_node_get_size (node);
if (group->phy_start + this_height == next_group->phy_start)
{
- unsigned long next_height = tower_node_get_height (next);
+ unsigned long next_height = tower_node_get_size (next);
tower_resize (t, node, this_height + next_height);
if (other_node != NULL && *other_node == next)
*other_node = tower_next (t, *other_node);
if (prev != NULL)
{
struct axis_group *prev_group = axis_group_from_tower_node (prev);
- unsigned long prev_height = tower_node_get_height (prev);
+ unsigned long prev_height = tower_node_get_size (prev);
if (prev_group->phy_start + prev_height == group->phy_start)
{
- unsigned long this_height = tower_node_get_height (node);
+ unsigned long this_height = tower_node_get_size (node);
group->phy_start = prev_group->phy_start;
tower_resize (t, node, this_height + prev_height);
if (other_node != NULL && *other_node == prev)
if (prev != NULL)
{
struct axis_group *prev_group = axis_group_from_tower_node (prev);
- unsigned long prev_height = tower_node_get_height (prev);
+ unsigned long prev_height = tower_node_get_size (prev);
struct axis_group *node_group = axis_group_from_tower_node (node);
assert (prev_group->phy_start + prev_height != node_group->phy_start);
}
d->callbacks->var_resized (d, var_get_dict_index (v), delta, d->cb_data);
}
}
+
+/* Called from variable.c to notify the dictionary that the variable's display width
+ has changed */
+void
+dict_var_display_width_changed (const struct variable *v)
+{
+ if ( var_has_vardict (v))
+ {
+ const struct vardict_info *vdi = var_get_vardict (v);
+ struct dictionary *d;
+
+ d = vdi->dict;
+
+ if ( d->callbacks && d->callbacks->var_display_width_changed )
+ d->callbacks->var_display_width_changed (d, var_get_dict_index (v), d->cb_data);
+ }
+}
+
void (*weight_changed) (struct dictionary *, int, void *);
void (*filter_changed) (struct dictionary *, int, void *);
void (*split_changed) (struct dictionary *, void *);
+ void (*var_display_width_changed) (struct dictionary *, int, void *);
};
void dict_set_callbacks (struct dictionary *, const struct dict_callbacks *,
/* Called by variable.c, defined in dictionary.c. */
void dict_var_changed (const struct variable *v);
void dict_var_resized (const struct variable *v, int delta);
+void dict_var_display_width_changed (const struct variable *v);
#endif /* data/vardict.h */
/* Sets V's display width to DISPLAY_WIDTH. */
void
-var_set_display_width (struct variable *v, int display_width)
+var_set_display_width (struct variable *v, int new_width)
{
- v->display_width = display_width;
+ int old_width = v->display_width;
+
+ v->display_width = new_width;
+
+ if ( old_width != new_width)
+ dict_var_display_width_changed (v);
+
dict_var_changed (v);
}
*dest = src;
}
+
+/* Set *DEST to the lower of *DEST and SRC */
+static inline void
+minimize_int (int *dest, int src)
+{
+ if (src < *dest)
+ *dest = src;
+}
+
+
+/* Set *DEST to the greater of *DEST and SRC */
+static inline void
+maximize_int (int *dest, int src)
+{
+ if (src > *dest)
+ *dest = src;
+}
+
+
#endif /* libpspp/misc.h */
const struct tower_node *);
static struct tower_node *prev_node (const struct tower *,
const struct tower_node *);
-static unsigned long int get_subtree_height (const struct abt_node *);
+static unsigned long int get_subtree_size (const struct abt_node *);
+static unsigned long int get_subtree_count (const struct abt_node *);
static void reaugment_tower_node (struct abt_node *,
const struct abt_node *,
const struct abt_node *,
const void *aux);
+/* Returns the height of the bottom of the given tower NODE.
+
+ The performance of this function is O(lg n) in the number of
+ nodes in the tower. It is often possible to avoid calling
+ this function, either by taking advantage of the NODE_START
+ parameter to tower_lookup or by incrementally keeping track of
+ height while iterating through a tower. In the former case
+ the asymptotic performance is no different, since tower_lookup
+ is also O(lg n), but in the latter case performance improves
+ from O(lg n) to O(1). */
+unsigned long int
+tower_node_get_level (const struct tower_node *node)
+{
+ const struct abt_node *p = &node->abt_node;
+ unsigned long level = get_subtree_size (p->down[0]);
+ while (p->up != NULL)
+ {
+ if (p == p->up->down[1])
+ level += (get_subtree_size (p->up->down[0])
+ + abt_to_tower_node (p->up)->size);
+ p = p->up;
+ }
+ return level;
+}
+
+/* Returns the index of the given tower NODE.
+
+ The performance of this function is O(lg n) in the number of
+ nodes in the tower. It is often possible to avoid calling
+ this function by keeping track of the index while iterating
+ through a tower. Doing so when possible will improve
+ performance from O(lg n) to O(1). */
+unsigned long int
+tower_node_get_index (const struct tower_node *node)
+{
+ const struct abt_node *p = &node->abt_node;
+ unsigned long index = get_subtree_count (p->down[0]);
+ while (p->up != NULL)
+ {
+ if (p == p->up->down[1])
+ index += get_subtree_count (p->up->down[0]) + 1;
+ p = p->up;
+ }
+ return index;
+}
+
/* Initializes T as an empty tower. */
void
tower_init (struct tower *t)
return t->abt.root == NULL;
}
+/* Returns the number of nodes in tower T. */
+unsigned long int
+tower_count (const struct tower *t)
+{
+ return get_subtree_count (t->abt.root);
+}
+
/* Returns the total height of tower T. */
unsigned long
tower_height (const struct tower *t)
{
- return get_subtree_height (t->abt.root);
+ return get_subtree_size (t->abt.root);
}
-/* Inserts node NEW with the specified HEIGHT into T just below
+/* Inserts node NEW with the specified SIZE into T just below
node UNDER, or at the top of T if UNDER is a null pointer. */
void
-tower_insert (struct tower *t, unsigned long height, struct tower_node *new,
+tower_insert (struct tower *t, unsigned long size, struct tower_node *new,
struct tower_node *under)
{
- assert (height > 0);
- new->height = height;
+ assert (size > 0);
+ new->size = size;
abt_insert_before (&t->abt, under ? &under->abt_node : NULL,
&new->abt_node);
t->cache_bottom = ULONG_MAX;
return next;
}
-/* Changes the height of NODE in tower T to NEW_HEIGHT. */
+/* Changes the size of NODE in tower T to NEW_SIZE. */
void
tower_resize (struct tower *t, struct tower_node *node,
- unsigned long new_height)
+ unsigned long new_size)
{
- assert (new_height > 0);
- node->height = new_height;
+ assert (new_size > 0);
+ node->size = new_size;
abt_reaugmented (&t->abt, &node->abt_node);
t->cache_bottom = ULONG_MAX;
}
assert (height < tower_height (t));
- if (height >= t->cache_bottom && height - t->cache_bottom < t->cache->height)
+ if (height >= t->cache_bottom && height - t->cache_bottom < t->cache->size)
{
*node_start = t->cache_bottom;
return t->cache;
p = t->abt.root;
for (;;)
{
- unsigned long left_height = get_subtree_height (p->down[0]);
- if (height < left_height)
+ unsigned long left_size = get_subtree_size (p->down[0]);
+ if (height < left_size)
{
/* Our goal height must lie within the left subtree. */
p = p->down[0];
{
/* Our goal height cannot be in the left subtree. */
struct tower_node *node = abt_to_tower_node (p);
- unsigned long int node_height = node->height;
+ unsigned long int node_size = node->size;
- height -= left_height;
- *node_start += left_height;
- if (height < node_height)
+ height -= left_size;
+ *node_start += left_size;
+ if (height < node_size)
{
/* Our goal height is in P. */
t->cache = node;
{
/* Our goal height is in the right subtree. */
p = p->down[1];
- height -= node_height;
- *node_start += node_height;
+ height -= node_size;
+ *node_start += node_size;
}
}
}
}
+/* Returns the node with the given 0-based INDEX, which must be
+ less than the number of nodes in T (as returned by
+ tower_count). */
+struct tower_node *
+tower_get (const struct tower *t_, unsigned long int index)
+{
+ struct tower *t = (struct tower *) t_;
+ struct abt_node *p;
+
+ assert (index < tower_count (t));
+
+ p = t->abt.root;
+ for (;;)
+ {
+ unsigned long left_count = get_subtree_count (p->down[0]);
+ if (index < left_count)
+ p = p->down[0];
+ else if (index == left_count)
+ return abt_to_tower_node (p);
+ else
+ {
+ p = p->down[1];
+ index -= left_count + 1;
+ }
+ }
+}
+
/* Returns the node at height 0 in tower T, or a null pointer if
T is empty. */
struct tower_node *
return abt_to_tower_node_null (abt_prev (&t->abt, &node->abt_node));
}
-/* Returns the total height of the nodes in the subtree rooted at
+/* Returns the total size of the nodes in the subtree rooted at
P, or 0 if P is null. */
static unsigned long int
-get_subtree_height (const struct abt_node *p)
+get_subtree_size (const struct abt_node *p)
+{
+ return p != NULL ? abt_to_tower_node (p)->subtree_size : 0;
+}
+
+/* Returns the total number of nodes in the subtree rooted at P,
+ or 0 if P is null. */
+static unsigned long int
+get_subtree_count (const struct abt_node *p)
{
- return p != NULL ? abt_to_tower_node (p)->subtree_height : 0;
+ return p != NULL ? abt_to_tower_node (p)->subtree_count : 0;
}
-/* Recalculates the subtree_height of NODE based on its LEFT and
- RIGHT children's subtree_heights. */
+/* Recalculates the subtree_size of NODE based on its LEFT and
+ RIGHT children's subtree_sizes. */
static void
reaugment_tower_node (struct abt_node *node_,
const struct abt_node *left,
const void *aux UNUSED)
{
struct tower_node *node = abt_to_tower_node (node_);
- node->subtree_height = node->height;
- if (left != NULL)
- node->subtree_height += abt_to_tower_node (left)->subtree_height;
- if (right != NULL)
- node->subtree_height += abt_to_tower_node (right)->subtree_height;
+ node->subtree_size = node->size;
+ node->subtree_count = 1;
+ if (left != NULL)
+ {
+ struct tower_node *left_node = abt_to_tower_node (left);
+ node->subtree_size += left_node->subtree_size;
+ node->subtree_count += left_node->subtree_count;
+ }
+ if (right != NULL)
+ {
+ struct tower_node *right_node = abt_to_tower_node (right);
+ node->subtree_size += right_node->subtree_size;
+ node->subtree_count += right_node->subtree_count;
+ }
}
This is the analogy behind this data structure. Each node in
the data structure has a "thickness", which is actually called
- the node's "height" because "thickness" is just too awkward a
+ the node's "size" because "thickness" is just too awkward a
name. The primary way to look up nodes is by a height from
the bottom of the tower; any height within a node retrieves
that node, not just the distance to the bottom of the node.
You can insert a new node between any two existing nodes, or
at either end, which shifts up the height of all the nodes
above it. You can also delete any node, which shifts down the
- height of all the nodes above it. */
+ height of all the nodes above it.
+
+ The tower data structure also implements efficient access to
+ nodes by index, i.e. by 0-based count of nodes from the bottom
+ of the tower. */
#ifndef LIBPSPP_TOWER_H
#define LIBPSPP_TOWER_H
struct tower_node
{
struct abt_node abt_node; /* ABT node. */
- unsigned long int subtree_height; /* Node's plus descendants' heights. */
- unsigned long int height; /* Height. */
+ unsigned long int subtree_size; /* Node size plus descendants' sizes. */
+ unsigned long int size; /* Size. */
+ unsigned long int subtree_count; /* Number of descendants, plus 1. */
};
-/* Returns the height of a tower node. */
+/* Returns the size of a tower node. */
static inline unsigned long
-tower_node_get_height (const struct tower_node *node)
+tower_node_get_size (const struct tower_node *node)
{
- return node->height;
+ return node->size;
}
+unsigned long int tower_node_get_level (const struct tower_node *);
+unsigned long int tower_node_get_index (const struct tower_node *);
+
/* A tower. */
struct tower
{
void tower_init (struct tower *);
bool tower_is_empty (const struct tower *);
+unsigned long int tower_count (const struct tower *);
unsigned long int tower_height (const struct tower *);
-void tower_insert (struct tower *, unsigned long int height,
+void tower_insert (struct tower *, unsigned long int size,
struct tower_node *new, struct tower_node *under);
struct tower_node *tower_delete (struct tower *, struct tower_node *);
void tower_resize (struct tower *, struct tower_node *,
- unsigned long int new_height);
+ unsigned long int new_size);
void tower_splice (struct tower *dst, struct tower_node *under,
struct tower *src,
struct tower_node *first, struct tower_node *last);
struct tower_node *tower_lookup (const struct tower *,
unsigned long int level,
unsigned long int *node_start);
+struct tower_node *tower_get (const struct tower *, unsigned long int index);
struct tower_node *tower_first (const struct tower *);
struct tower_node *tower_last (const struct tower *);
struct tower_node *tower_next (const struct tower *,
bin_PROGRAMS += src/ui/gui/psppire
src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GLADE_CFLAGS) -Wall \
- -DINSTALLDIR=\"$(bindir)\"
+ -DINSTALLDIR=\"$(bindir)\" -DGDK_MULTIHEAD_SAFE=1
src_ui_gui_psppire_LDFLAGS = \
src/ui/gui/psppire-buttonbox.h \
src/ui/gui/psppire-hbuttonbox.h \
src/ui/gui/psppire-vbuttonbox.h \
- src/ui/gui/psppire-case-file.c \
- src/ui/gui/psppire-case-file.h \
src/ui/gui/psppire-data-editor.c \
src/ui/gui/psppire-data-editor.h \
src/ui/gui/psppire-data-store.c \
static GtkWidget * create_data_sheet_variable_popup_menu (struct data_editor *);
+
+static GtkWidget * create_var_sheet_variable_popup_menu (struct data_editor *);
+
static GtkWidget * create_data_sheet_cases_popup_menu (struct data_editor *);
static void register_data_editor_actions (struct data_editor *de);
static void insert_case (GtkAction *a, gpointer data);
static void toggle_value_labels (GtkToggleAction *a, gpointer data);
+static void toggle_split_window (GtkToggleAction *ta, gpointer data);
+
/* Callback for when the dictionary changes properties*/
static void on_weight_change (GObject *, gint, gpointer);
"activate",
G_CALLBACK (minimise_all_windows), NULL);
+ de->toggle_split_window =
+ gtk_toggle_action_new ("toggle-split-window",
+ _("_Split Window"),
+ _("Split the window vertically and horizontally"),
+ "pspp-split-window");
+
+ g_signal_connect (de->toggle_split_window, "toggled",
+ G_CALLBACK (toggle_split_window),
+ de);
+
+ gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window),
+ get_widget_assert (de->xml,
+ "windows_split"));
de->data_sheet_variable_popup_menu =
GTK_MENU (create_data_sheet_variable_popup_menu (de));
+ de->var_sheet_variable_popup_menu =
+ GTK_MENU (create_var_sheet_variable_popup_menu (de));
+
de->data_sheet_cases_popup_menu =
GTK_MENU (create_data_sheet_cases_popup_menu (de));
g_object_set (de->data_editor,
- "column-menu", de->data_sheet_variable_popup_menu, NULL);
-
+ "datasheet-column-menu", de->data_sheet_variable_popup_menu,
+ "datasheet-row-menu", de->data_sheet_cases_popup_menu,
+ "varsheet-row-menu", de->var_sheet_variable_popup_menu,
+ NULL);
- g_object_set (de->data_editor,
- "row-menu", de->data_sheet_cases_popup_menu, NULL);
return de;
}
fonts_activate (GtkMenuItem *menuitem, gpointer data)
{
struct data_editor *de = data;
+ PangoFontDescription *current_font;
+ gchar *font_name;
GtkWidget *dialog =
gtk_font_selection_dialog_new (_("Font Selection"));
+
+ current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
+ font_name = pango_font_description_to_string (current_font);
+
+ gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
+
+ g_free (font_name);
+
gtk_window_set_transient_for (GTK_WINDOW (dialog),
GTK_WINDOW (get_widget_assert (de->xml,
"data_editor")));
+static void
+toggle_split_window (GtkToggleAction *ta, gpointer data)
+{
+ struct data_editor *de = data;
+
+ psppire_data_editor_split_window (de->data_editor,
+ gtk_toggle_action_get_active (ta));
+}
+
+
+
+
static void
file_quit (GtkCheckMenuItem *menuitem, gpointer data)
{
}
+static GtkWidget *
+create_var_sheet_variable_popup_menu (struct data_editor *de)
+{
+ GtkWidget *menu = gtk_menu_new ();
+
+ GtkWidget *insert_variable =
+ gtk_menu_item_new_with_label (_("Insert Variable"));
+
+ GtkWidget *delete_variable =
+ gtk_menu_item_new_with_label (_("Clear"));
+
+
+ gtk_action_connect_proxy (de->delete_variables,
+ delete_variable);
+
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
+
+ g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
+ G_CALLBACK (gtk_action_activate),
+ de->insert_variable);
+
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+ gtk_separator_menu_item_new ());
+
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable);
+
+
+ gtk_widget_show_all (menu);
+
+ return menu;
+}
+
+
+
\f
static void
<property name="use_underline">True</property>
</widget>
</child>
+ <child>
+ <widget class="GtkCheckMenuItem" id="windows_split">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Split</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
</widget>
</child>
</widget>
GtkAction *invoke_oneway_anova_dialog;
GtkAction *invoke_t_test_one_sample_dialog;
+ GtkToggleAction *toggle_split_window;
+
/* Actions which do things */
GtkAction *insert_variable;
GtkMenu *data_sheet_variable_popup_menu;
GtkMenu *data_sheet_cases_popup_menu;
+ GtkMenu *var_sheet_variable_popup_menu;
+
PsppireDataEditor *data_editor;
gboolean save_as_portable;
NULL);
fd.dict = vs->dict;
- fd.data = ds->case_file->datasheet;
+ fd.data = ds->datasheet;
fd.variable_entry = get_widget_assert (fd.xml, "find-variable-entry");
fd.value_entry = get_widget_assert (fd.xml, "find-value-entry");
reader = proc_extract_active_file_data (the_dataset);
if (!lazy_casereader_destroy (reader, lazy_serial))
- psppire_data_store_set_case_file (the_data_store,
- psppire_case_file_new (reader));
+ psppire_data_store_set_reader (the_data_store, reader);
som_flush ();
-#ifdef G_ENABLE_DEBUG
-# define g_marshal_value_peek_int(v) g_value_get_int (v)
-#else
-# define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#endif
-
-
-/* VOID:INT,INT,INT */
-void
-marshaller_VOID__INT_INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gint arg_3,
- gpointer data2);
- register GMarshalFunc_VOID__INT_INT_INT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- g_marshal_value_peek_int (param_values + 3),
- data2);
-}
-
/* Create a deep copy of SRC */
GtkListStore *
clone_list_store (const GtkListStore *src)
+++ /dev/null
-/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2006 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 "psppire-case-file.h"
-
-#include <gtksheet/gtkextra-marshal.h>
-
-#include <data/format.h>
-#include <data/case.h>
-#include <data/data-in.h>
-#include <data/datasheet.h>
-#include <data/casereader.h>
-#include <math/sort.h>
-#include <libpspp/misc.h>
-
-#include "xalloc.h"
-#include "xmalloca.h"
-
-/* --- prototypes --- */
-static void psppire_case_file_class_init (PsppireCaseFileClass *class);
-static void psppire_case_file_init (PsppireCaseFile *case_file);
-static void psppire_case_file_finalize (GObject *object);
-
-
-/* --- variables --- */
-static GObjectClass *parent_class = NULL;
-
-enum {CASE_CHANGED,
- CASE_INSERTED,
- CASES_DELETED,
- n_SIGNALS};
-
-static guint signals [n_SIGNALS];
-
-
-/* --- functions --- */
-/**
- * psppire_case_file_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_case_file_get_type (void)
-{
- static GType object_type = 0;
-
- if (!object_type)
- {
- static const GTypeInfo object_info = {
- sizeof (PsppireCaseFileClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) psppire_case_file_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (PsppireCaseFile),
- 0, /* n_preallocs */
- (GInstanceInitFunc) psppire_case_file_init,
- };
-
- object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireCaseFile",
- &object_info, 0);
- }
-
- return object_type;
-}
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_DATASHEET,
- PROP_READER
-};
-
-
-
-
-static void
-psppire_case_file_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-
-{
- PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object);
-
- switch (prop_id)
- {
- case PROP_READER:
- cf->datasheet = datasheet_create (g_value_get_pointer (value));
- cf->accessible = TRUE;
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- };
-}
-
-static void
-psppire_case_file_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object);
-
- switch (prop_id)
- {
- case PROP_DATASHEET:
- g_value_set_pointer (value, cf->datasheet);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- };
-}
-
-
-static void
-psppire_case_file_class_init (PsppireCaseFileClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GParamSpec *datasheet_spec ;
- GParamSpec *reader_spec ;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class->finalize = psppire_case_file_finalize;
-
- datasheet_spec =
- g_param_spec_pointer ("datasheet",
- "Datasheet",
- "A pointer to the datasheet belonging to this object",
- G_PARAM_READABLE );
- reader_spec =
- g_param_spec_pointer ("casereader",
- "CaseReader",
- "A pointer to the case reader from which this object is constructed",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE );
-
- object_class->set_property = psppire_case_file_set_property;
- object_class->get_property = psppire_case_file_get_property;
-
- g_object_class_install_property (object_class,
- PROP_DATASHEET,
- datasheet_spec);
-
- g_object_class_install_property (object_class,
- PROP_READER,
- reader_spec);
-
- signals [CASE_CHANGED] =
- g_signal_new ("case-changed",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
-
- signals [CASE_INSERTED] =
- g_signal_new ("case-inserted",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
-
- signals [CASES_DELETED] =
- g_signal_new ("cases-deleted",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- gtkextra_VOID__INT_INT,
- G_TYPE_NONE,
- 2,
- G_TYPE_INT, G_TYPE_INT);
-}
-
-static void
-psppire_case_file_finalize (GObject *object)
-{
- PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object);
-
- if ( cf->accessible)
- datasheet_destroy (cf->datasheet);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-psppire_case_file_init (PsppireCaseFile *cf)
-{
- cf->datasheet = NULL;
- cf->accessible = FALSE;
-}
-
-
-/**
- * psppire_case_file_new:
- * @returns: a new #PsppireCaseFile object
- *
- * Creates a new #PsppireCaseFile.
- */
-PsppireCaseFile*
-psppire_case_file_new (struct casereader *reader)
-{
- return g_object_new (G_TYPE_PSPPIRE_CASE_FILE,
- "casereader", reader,
- NULL);
-}
-
-
-gboolean
-psppire_case_file_delete_cases (PsppireCaseFile *cf, casenumber n_cases, casenumber first)
-{
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->datasheet, FALSE);
- g_return_val_if_fail (cf->accessible, FALSE);
-
- g_return_val_if_fail (first + n_cases <=
- psppire_case_file_get_case_count (cf), FALSE);
-
- datasheet_delete_rows (cf->datasheet, first, n_cases);
-
- g_signal_emit (cf, signals [CASES_DELETED], 0, first, n_cases);
-
- return TRUE;
-}
-
-/* Insert case CC into the case file before POSN */
-gboolean
-psppire_case_file_insert_case (PsppireCaseFile *cf,
- struct ccase *cc,
- casenumber posn)
-{
- struct ccase tmp;
- bool result ;
-
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->datasheet, FALSE);
- g_return_val_if_fail (cf->accessible, FALSE);
-
- case_clone (&tmp, cc);
- result = datasheet_insert_rows (cf->datasheet, posn, &tmp, 1);
-
- if ( result )
- g_signal_emit (cf, signals [CASE_INSERTED], 0, posn);
- else
- g_warning ("Cannot insert case at position %ld\n", posn);
-
- return result;
-}
-
-
-casenumber
-psppire_case_file_get_case_count (const PsppireCaseFile *cf)
-{
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->accessible, FALSE);
-
- if ( ! cf->datasheet)
- return 0;
-
- return datasheet_get_row_cnt (cf->datasheet);
-}
-
-/* Copies the IDXth value from case CASENUM into VALUE.
- If VALUE is null, then memory is allocated is allocated with
- malloc. Returns the value if successful, NULL on failure. */
-union value *
-psppire_case_file_get_value (const PsppireCaseFile *cf,
- casenumber casenum, size_t idx,
- union value *value, int width)
-{
- bool allocated;
-
- g_return_val_if_fail (cf, false);
- g_return_val_if_fail (cf->datasheet, false);
-
- g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), false);
-
- if (value == NULL)
- {
- value = xnmalloc (value_cnt_from_width (width), sizeof *value);
- allocated = true;
- }
- else
- allocated = false;
- if (!datasheet_get_value (cf->datasheet, casenum, idx, value, width))
- {
- if (allocated)
- free (value);
- value = NULL;
- }
- return value;
-}
-
-void
-psppire_case_file_clear (PsppireCaseFile *cf)
-{
- datasheet_destroy (cf->datasheet);
- cf->datasheet = NULL;
- g_signal_emit (cf, signals [CASES_DELETED], 0, 0, -1);
-}
-
-/* Set the IDXth value of case C to V.
- Returns true if successful, false on I/O error. */
-gboolean
-psppire_case_file_set_value (PsppireCaseFile *cf, casenumber casenum, gint idx,
- union value *v, gint width)
-{
- bool ok;
-
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->datasheet, FALSE);
-
- g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), FALSE);
-
- ok = datasheet_put_value (cf->datasheet, casenum, idx, v, width);
- if (ok)
- g_signal_emit (cf, signals [CASE_CHANGED], 0, casenum);
- return ok;
-}
-
-
-
-/* Set the IDXth value of case C using D_IN */
-gboolean
-psppire_case_file_data_in (PsppireCaseFile *cf, casenumber casenum, gint idx,
- struct substring input, const struct fmt_spec *fmt)
-{
- union value *value = NULL;
- int width;
- bool ok;
-
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->datasheet, FALSE);
-
- g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), FALSE);
-
- width = fmt_var_width (fmt);
- value = xmalloca (value_cnt_from_width (width) * sizeof *value);
- ok = (datasheet_get_value (cf->datasheet, casenum, idx, value, width)
- && data_in (input, LEGACY_NATIVE, fmt->type, 0, 0, 0, value, width)
- && datasheet_put_value (cf->datasheet, casenum, idx, value, width));
-
- if (ok)
- g_signal_emit (cf, signals [CASE_CHANGED], 0, casenum);
-
- freea (value);
-
- return TRUE;
-}
-
-
-void
-psppire_case_file_sort (PsppireCaseFile *cf, const struct subcase *ordering)
-{
- struct casereader *sorted_data;
- gint c;
-
- sorted_data = sort_execute (datasheet_make_reader (cf->datasheet), ordering);
- cf->datasheet = datasheet_create (sorted_data);
-
- /* FIXME: Need to have a signal to change a range of cases, instead of
- calling a signal many times */
- for ( c = 0 ; c < datasheet_get_row_cnt (cf->datasheet) ; ++c )
- g_signal_emit (cf, signals [CASE_CHANGED], 0, c);
-}
-
-
-/* Resize the cases in the casefile, by inserting N_VALUES into every
- one of them at the position immediately preceeding WHERE.
-*/
-gboolean
-psppire_case_file_insert_values (PsppireCaseFile *cf,
- gint n_values, gint where)
-{
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->accessible, FALSE);
-
- if ( n_values == 0 )
- return FALSE;
-
- g_assert (n_values > 0);
-
- if ( ! cf->datasheet )
- cf->datasheet = datasheet_create (NULL);
-
- {
- union value *values = xcalloc (n_values, sizeof *values);
- datasheet_insert_columns (cf->datasheet, values, n_values, where);
- free (values);
- }
-
- return TRUE;
-}
-
-
-/* Fills C with the CASENUMth case.
- Returns true on success, false otherwise.
- */
-gboolean
-psppire_case_file_get_case (const PsppireCaseFile *cf, casenumber casenum,
- struct ccase *c)
-{
- g_return_val_if_fail (cf, FALSE);
- g_return_val_if_fail (cf->datasheet, FALSE);
-
- return datasheet_get_row (cf->datasheet, casenum, c);
-}
-
-
-
-struct casereader *
-psppire_case_file_make_reader (PsppireCaseFile *cf)
-{
- struct casereader *r = datasheet_make_reader (cf->datasheet);
- cf->accessible = FALSE;
- return r;
-}
-
+++ /dev/null
-/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2006 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 __CASE_FILE_H__
-#define __CASE_FILE_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include <libpspp/str.h>
-#include <data/case.h>
-
-
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_CASE_FILE (psppire_case_file_get_type ())
-#define PSPPIRE_CASE_FILE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFile))
-#define PSPPIRE_CASE_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass))
-#define G_IS_PSPPIRE_CASE_FILE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_CASE_FILE))
-#define G_IS_PSPPIRE_CASE_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_CASE_FILE))
-#define PSPPIRE_CASE_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass))
-
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireCaseFile PsppireCaseFile;
-typedef struct _PsppireCaseFileClass PsppireCaseFileClass;
-
-struct ccase;
-struct casereader;
-
-struct _PsppireCaseFile
-{
- GObject parent;
-
- /* <private> */
- struct datasheet *datasheet;
- gboolean accessible;
-};
-
-
-struct _PsppireCaseFileClass
-{
- GObjectClass parent_class;
-};
-
-
-/* -- PsppireCaseFile --- */
-GType psppire_case_file_get_type (void);
-
-PsppireCaseFile *psppire_case_file_new (struct casereader *);
-
-gboolean psppire_case_file_insert_case (PsppireCaseFile *cf, struct ccase *c, casenumber row);
-
-inline casenumber psppire_case_file_get_case_count (const PsppireCaseFile *cf);
-
-
-union value * psppire_case_file_get_value (const PsppireCaseFile *cf,
- casenumber, size_t idx,
- union value *, int width);
-
-struct fmt_spec;
-
-gboolean psppire_case_file_data_in (PsppireCaseFile *cf, casenumber c, gint idx,
- struct substring input,
- const struct fmt_spec *);
-
-gboolean psppire_case_file_set_value (PsppireCaseFile *cf, casenumber casenum,
- gint idx, union value *v, gint width);
-
-void psppire_case_file_clear (PsppireCaseFile *cf);
-
-
-gboolean psppire_case_file_delete_cases (PsppireCaseFile *cf, casenumber n_rows,
- casenumber first);
-
-gboolean psppire_case_file_insert_values (PsppireCaseFile *cf, gint n_values, gint where);
-
-struct subcase;
-
-void psppire_case_file_sort (PsppireCaseFile *cf, const struct subcase *);
-
-gboolean psppire_case_file_get_case (const PsppireCaseFile *cf,
- casenumber casenum,
- struct ccase *c);
-
-
-struct casereader * psppire_case_file_make_reader (PsppireCaseFile *cf);
-
-
-G_END_DECLS
-
-#endif /* __PSPPIRE_CASE_FILE_H__ */
/* PSPPIRE - a graphical user interface for PSPP.
- Copyrigght (C) 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008 Free Software Foundation, Inc.
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
#include <config.h>
#include <gtk/gtksignal.h>
#include <gtk/gtk.h>
-#include <gtksheet/gtksheet.h>
+#include <gtksheet/gtkextra-sheet.h>
#include "psppire-data-editor.h"
#include "psppire-var-sheet.h"
-#include <gtksheet/gsheet-hetero-column.h>
#include <language/syntax-string-source.h>
#include "psppire-data-store.h"
+#include <gtksheet/psppire-axis-impl.h>
#include "helper.h"
+#include <gtksheet/gtkxpaned.h>
#include <gettext.h>
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
+static void psppire_data_editor_remove_split (PsppireDataEditor *de);
+static void psppire_data_editor_set_split (PsppireDataEditor *de);
+
enum {
DATA_SELECTION_CHANGED,
DATA_AVAILABLE_CHANGED,
-static void popup_variable_menu (GtkSheet *sheet, gint column,
- GdkEventButton *event, gpointer data);
+static void popup_variable_column_menu (GtkSheet *sheet, gint column,
+ GdkEventButton *event, gpointer data);
+
+static void popup_variable_row_menu (GtkSheet *sheet, gint row,
+ GdkEventButton *event, gpointer data);
+
static void popup_cases_menu (GtkSheet *sheet, gint row,
GdkEventButton *event, gpointer data);
+
/* Callback which occurs when the data sheet's column title
is double clicked */
static gboolean
on_data_column_clicked (PsppireDataEditor *de, gint col, gpointer data)
{
-
+ GtkSheetRange visible_range;
gint current_row, current_column;
- gtk_notebook_set_current_page (GTK_NOTEBOOK (de), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (de),
+ PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
gtk_sheet_get_active_cell (GTK_SHEET (de->var_sheet),
¤t_row, ¤t_column);
gtk_sheet_set_active_cell (GTK_SHEET (de->var_sheet), col, current_column);
+
+ gtk_sheet_get_visible_range (GTK_SHEET (de->var_sheet), &visible_range);
+
+ if ( col < visible_range.row0 || col > visible_range.rowi)
+ gtk_sheet_moveto (GTK_SHEET (de->var_sheet), col, current_column, 0.5, 0.5);
+
+
return FALSE;
}
gtk_notebook_set_current_page (GTK_NOTEBOOK(de), PSPPIRE_DATA_EDITOR_DATA_VIEW);
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet),
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]),
¤t_row, ¤t_column);
- gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), current_row, row);
+ gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), current_row, row);
- gtk_sheet_get_visible_range (GTK_SHEET (de->data_sheet), &visible_range);
+ gtk_sheet_get_visible_range (GTK_SHEET (de->data_sheet[0]), &visible_range);
if ( row < visible_range.col0 || row > visible_range.coli)
- {
- gtk_sheet_moveto (GTK_SHEET (de->data_sheet),
- current_row, row, 0, 0);
- }
+ gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), -1, row, 0.5, 0.5);
return FALSE;
}
+/* Moves the focus to a new cell.
+ Returns TRUE iff the move should be disallowed */
+static gboolean
+traverse_cell_callback (GtkSheet *sheet,
+ GtkSheetCell *existing_cell,
+ GtkSheetCell *new_cell,
+ gpointer data)
+{
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+ const PsppireDict *dict = de->data_store->dict;
+
+ if ( new_cell->col >= psppire_dict_get_var_cnt (dict))
+ return TRUE;
+
+ return FALSE;
+}
+
enum
{
PROP_0,
PROP_DATA_STORE,
PROP_VAR_STORE,
- PROP_COLUMN_MENU,
- PROP_ROW_MENU,
+ PROP_VS_ROW_MENU,
+ PROP_DS_COLUMN_MENU,
+ PROP_DS_ROW_MENU,
PROP_VALUE_LABELS,
PROP_CURRENT_CASE,
PROP_CURRENT_VAR,
- PROP_DATA_SELECTED
+ PROP_DATA_SELECTED,
+ PROP_SPLIT_WINDOW
};
+
+#define DEFAULT_ROW_HEIGHT 25
+
+static void
+new_data_callback (PsppireDataStore *ds, gpointer data)
+{
+ gint i;
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+
+ casenumber n_cases = psppire_data_store_get_case_count (ds);
+
+ for (i = 0; i < 2; ++i)
+ {
+ psppire_axis_impl_clear (de->vaxis[i]);
+ psppire_axis_impl_append_n (de->vaxis[i], n_cases, DEFAULT_ROW_HEIGHT);
+ }
+}
+
+static void
+case_inserted_callback (PsppireDataStore *ds, gint before, gpointer data)
+{
+ gint i;
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+
+ for (i = 0; i < 2; ++i)
+ psppire_axis_impl_insert (de->vaxis[i], before, DEFAULT_ROW_HEIGHT);
+}
+
+
+static void
+cases_deleted_callback (PsppireDataStore *ds, gint first, gint n_cases, gpointer data)
+{
+ gint i;
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+
+ for (i = 0; i < 2; ++i)
+ psppire_axis_impl_delete (de->vaxis[0], first, n_cases);
+}
+
+
+
+/* Return the width (in pixels) of an upper case M when rendered in the
+ current font of W
+*/
+static gint
+width_of_m (GtkWidget *w)
+{
+ PangoRectangle rect;
+ PangoLayout *layout = gtk_widget_create_pango_layout (w, "M");
+
+ pango_layout_get_pixel_extents (layout, NULL, &rect);
+
+ g_object_unref (layout);
+
+ return rect.width;
+}
+
+/* Callback for the axis' resize signal.
+ Changes the variable's display width */
+static void
+rewidth_variable (GtkWidget *w, gint unit, glong size)
+{
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (w);
+
+ const PsppireDict *dict = de->data_store->dict;
+ struct variable *var = psppire_dict_get_variable (dict, unit);
+
+ if (NULL == var)
+ return;
+
+ var_set_display_width (var, size / (float) width_of_m (w));
+}
+
+
+static void
+new_variables_callback (PsppireDict *dict, gpointer data)
+{
+ gint v;
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+ gint m_width = width_of_m (GTK_WIDGET (de));
+
+ PsppireAxisImpl *vaxis;
+ g_object_get (de->var_sheet, "vertical-axis", &vaxis, NULL);
+
+ psppire_axis_impl_clear (vaxis);
+ psppire_axis_impl_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
+
+ g_signal_connect_swapped (de->haxis, "resize-unit",
+ G_CALLBACK (rewidth_variable), de);
+
+ psppire_axis_impl_clear (de->haxis);
+
+ for (v = 0 ; v < psppire_dict_get_var_cnt (dict); ++v)
+ {
+ const struct variable *var = psppire_dict_get_variable (dict, v);
+
+ psppire_axis_impl_append (de->haxis, m_width * var_get_display_width (var));
+ }
+}
+
+static void
+insert_variable_callback (PsppireDict *dict, gint x, gpointer data)
+{
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+
+ gint m_width = width_of_m (GTK_WIDGET (de));
+
+ PsppireAxisImpl *var_vaxis;
+
+ const struct variable *var = psppire_dict_get_variable (dict, x);
+
+ g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
+
+ psppire_axis_impl_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
+
+
+ psppire_axis_impl_insert (de->haxis, x, m_width * var_get_display_width (var));
+}
+
+
+static void
+delete_variable_callback (PsppireDict *dict, gint posn,
+ gint x UNUSED, gint y UNUSED, gpointer data)
+{
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+
+ PsppireAxisImpl *var_vaxis;
+ g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
+
+ psppire_axis_impl_delete (var_vaxis, posn, 1);
+
+ psppire_axis_impl_delete (de->haxis, posn, 1);
+}
+
+
+static void
+rewidth_variable_callback (PsppireDict *dict, gint posn, gpointer data)
+{
+ PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+ gint m_width = width_of_m (GTK_WIDGET (de));
+
+ const struct variable *var = psppire_dict_get_variable (dict, posn);
+
+ gint var_width = var_get_display_width (var);
+
+ /* Don't allow zero width */
+ if ( var_width < 1 )
+ var_width = 1;
+
+ psppire_axis_impl_resize (de->haxis, posn, m_width * var_width);
+}
+
+
static void
psppire_data_editor_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
+ int i;
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (object);
switch (prop_id)
{
+ case PROP_SPLIT_WINDOW:
+ psppire_data_editor_split_window (de, g_value_get_boolean (value));
+ break;
case PROP_DATA_STORE:
if ( de->data_store) g_object_unref (de->data_store);
de->data_store = g_value_get_pointer (value);
g_object_ref (de->data_store);
- g_object_set (de->data_sheet,
- "row-geometry", de->data_store,
- "column-geometry", de->data_store,
- "model", de->data_store,
- NULL);
+ for (i = 0 ; i < 4 ; ++i )
+ g_object_set (de->data_sheet[i],
+ "model", de->data_store,
+ NULL);
+
+ g_signal_connect (de->data_store->dict, "backend-changed",
+ G_CALLBACK (new_variables_callback), de);
+
+ g_signal_connect (de->data_store->dict, "variable-inserted",
+ G_CALLBACK (insert_variable_callback), de);
+
+ g_signal_connect (de->data_store->dict, "variable-deleted",
+ G_CALLBACK (delete_variable_callback), de);
+
+ g_signal_connect (de->data_store->dict, "variable-display-width-changed",
+ G_CALLBACK (rewidth_variable_callback), de);
+
+ g_signal_connect (de->data_store, "backend-changed",
+ G_CALLBACK (new_data_callback), de);
+
+ g_signal_connect (de->data_store, "case-inserted",
+ G_CALLBACK (case_inserted_callback), de);
+
+ g_signal_connect (de->data_store, "cases-deleted",
+ G_CALLBACK (cases_deleted_callback), de);
+
break;
case PROP_VAR_STORE:
if ( de->var_store) g_object_unref (de->var_store);
g_object_ref (de->var_store);
g_object_set (de->var_sheet,
- "row-geometry", de->var_store,
"model", de->var_store,
NULL);
break;
- case PROP_COLUMN_MENU:
+ case PROP_VS_ROW_MENU:
+ {
+ GObject *menu = g_value_get_object (value);
+
+ g_signal_connect (de->var_sheet, "button-event-row",
+ G_CALLBACK (popup_variable_row_menu), menu);
+ }
+ break;
+ case PROP_DS_COLUMN_MENU:
{
GObject *menu = g_value_get_object (value);
- g_signal_connect (de->data_sheet, "button-event-column",
- G_CALLBACK (popup_variable_menu), menu);
+ g_signal_connect (de->data_sheet[0], "button-event-column",
+ G_CALLBACK (popup_variable_column_menu), menu);
}
break;
- case PROP_ROW_MENU:
+ case PROP_DS_ROW_MENU:
{
GObject *menu = g_value_get_object (value);
- g_signal_connect (de->data_sheet, "button-event-row",
+ g_signal_connect (de->data_sheet[0], "button-event-row",
G_CALLBACK (popup_cases_menu), menu);
}
break;
switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (object)))
{
case PSPPIRE_DATA_EDITOR_DATA_VIEW:
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col);
- gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), row, var);
- gtk_sheet_moveto (GTK_SHEET (de->data_sheet), row, var, 0.5, 0.5);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col);
+ gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), row, var);
+ gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), -1, var, 0.5, 0.5);
break;
case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
gtk_sheet_get_active_cell (GTK_SHEET (de->var_sheet), &row, &col);
gtk_sheet_set_active_cell (GTK_SHEET (de->var_sheet), var, col);
- gtk_sheet_moveto (GTK_SHEET (de->var_sheet), var, col, 0.5, 0.5);
+ gtk_sheet_moveto (GTK_SHEET (de->var_sheet), var, -1, 0.5, 0.5);
break;
default:
g_assert_not_reached ();
{
gint row, col;
gint case_num = g_value_get_long (value);
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col);
- gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), case_num, col);
- gtk_sheet_moveto (GTK_SHEET (de->data_sheet), case_num, col, 0.5, 0.5);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col);
+ gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), case_num, col);
+ gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), case_num, -1, 0.5, 0.5);
}
break;
case PROP_VALUE_LABELS:
switch (prop_id)
{
+ case PROP_SPLIT_WINDOW:
+ g_value_set_boolean (value, de->split);
+ break;
case PROP_DATA_STORE:
g_value_set_pointer (value, de->data_store);
break;
case PROP_CURRENT_CASE:
{
gint row, column;
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column);
g_value_set_long (value, row);
}
break;
case PROP_CURRENT_VAR:
{
gint row, column;
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column);
g_value_set_long (value, column);
}
break;
GParamSpec *data_store_spec ;
GParamSpec *var_store_spec ;
GParamSpec *column_menu_spec;
- GParamSpec *row_menu_spec;
+ GParamSpec *ds_row_menu_spec;
+ GParamSpec *vs_row_menu_spec;
GParamSpec *value_labels_spec;
GParamSpec *current_case_spec;
GParamSpec *current_var_spec;
GParamSpec *data_selected_spec;
+ GParamSpec *split_window_spec;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
var_store_spec);
column_menu_spec =
- g_param_spec_object ("column-menu",
- "Column Menu",
- "A menu to be displayed when button 3 is pressed in the column title buttons",
+ g_param_spec_object ("datasheet-column-menu",
+ "Data Sheet Column Menu",
+ "A menu to be displayed when button 3 is pressed in thedata sheet's column title buttons",
GTK_TYPE_MENU,
G_PARAM_WRITABLE);
g_object_class_install_property (object_class,
- PROP_COLUMN_MENU,
+ PROP_DS_COLUMN_MENU,
column_menu_spec);
- row_menu_spec =
- g_param_spec_object ("row-menu",
- "Row Menu",
- "A menu to be displayed when button 3 is pressed in the row title buttons",
+ ds_row_menu_spec =
+ g_param_spec_object ("datasheet-row-menu",
+ "Data Sheet Row Menu",
+ "A menu to be displayed when button 3 is pressed in the data sheet's row title buttons",
+ GTK_TYPE_MENU,
+ G_PARAM_WRITABLE);
+
+ g_object_class_install_property (object_class,
+ PROP_DS_ROW_MENU,
+ ds_row_menu_spec);
+
+
+ vs_row_menu_spec =
+ g_param_spec_object ("varsheet-row-menu",
+ "Variable Sheet Row Menu",
+ "A menu to be displayed when button 3 is pressed in the variable sheet's row title buttons",
GTK_TYPE_MENU,
G_PARAM_WRITABLE);
g_object_class_install_property (object_class,
- PROP_ROW_MENU,
- row_menu_spec);
+ PROP_VS_ROW_MENU,
+ vs_row_menu_spec);
+
value_labels_spec =
g_param_spec_boolean ("value-labels",
+ split_window_spec =
+ g_param_spec_boolean ("split",
+ "Split Window",
+ "True iff the data sheet is split",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE);
+
+ g_object_class_install_property (object_class,
+ PROP_SPLIT_WINDOW,
+ split_window_spec);
+
data_editor_signals [DATA_SELECTION_CHANGED] =
g_signal_new ("data-selection-changed",
G_TYPE_FROM_CLASS (klass),
/* Update the data_ref_entry with the reference of the active cell */
static gint
-update_data_ref_entry (const GtkSheet *sheet, gint row, gint col, gpointer data)
+update_data_ref_entry (const GtkSheet *sheet,
+ gint row, gint col,
+ gint old_row, gint old_col,
+ gpointer data)
{
PsppireDataEditor *de = data;
const gchar *text = gtk_entry_get_text (entry);
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column);
if ( row == -1 || column == -1)
return;
psppire_data_store_set_string (de->data_store, text, row, column);
}
-
static void on_activate (PsppireDataEditor *de);
-static void on_deactivate (PsppireDataEditor *de);
static gboolean on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p, gint pagenum, gpointer data);
static void on_select_range (PsppireDataEditor *de);
}
+static void
+init_sheet (PsppireDataEditor *de, int i,
+ GtkAdjustment *hadj, GtkAdjustment *vadj,
+ PsppireAxisImpl *vaxis,
+ PsppireAxisImpl *haxis
+ )
+{
+ de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj);
+
+ de->data_sheet[i] = gtk_sheet_new (NULL);
+
+ g_object_set (de->sheet_bin[i],
+ "border-width", 3,
+ "shadow-type", GTK_SHADOW_ETCHED_IN,
+ NULL);
+
+ g_object_set (haxis, "default-size", 75, NULL);
+ g_object_set (vaxis, "default-size", 25, NULL);
+
+ g_object_set (de->data_sheet[i],
+ "horizontal-axis", haxis,
+ "vertical-axis", vaxis,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (de->sheet_bin[i]), de->data_sheet[i]);
+
+ g_signal_connect (de->data_sheet[i], "traverse",
+ G_CALLBACK (traverse_cell_callback), de);
+
+ gtk_widget_show (de->sheet_bin[i]);
+}
+
+
+static void
+init_data_sheet (PsppireDataEditor *de)
+{
+ GtkAdjustment *vadj0, *hadj0;
+ GtkAdjustment *vadj1, *hadj1;
+ GtkWidget *sheet ;
+
+ de->vaxis[0] = psppire_axis_impl_new ();
+ de->vaxis[1] = psppire_axis_impl_new ();
+
+ /* Txoxovhere's only one horizontal axis, since the
+ column widths are parameters of the variables */
+ de->haxis = psppire_axis_impl_new ();
+
+
+ de->split = TRUE;
+ de->paned = gtk_xpaned_new ();
+
+ init_sheet (de, 0, NULL, NULL, de->vaxis[0], de->haxis);
+ gtk_widget_show (de->sheet_bin[0]);
+ vadj0 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[0]));
+ hadj0 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[0]));
+
+ g_object_set (de->sheet_bin[0], "vscrollbar-policy", GTK_POLICY_NEVER, NULL);
+ g_object_set (de->sheet_bin[0], "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
+
+ init_sheet (de, 1, NULL, vadj0, de->vaxis[0], de->haxis);
+ gtk_widget_show (de->sheet_bin[1]);
+ sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[1]));
+ gtk_sheet_hide_row_titles (GTK_SHEET (sheet));
+ hadj1 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[1]));
+ g_object_set (de->sheet_bin[1], "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
+ g_object_set (de->sheet_bin[1], "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
+
+ init_sheet (de, 2, hadj0, NULL, de->vaxis[1], de->haxis);
+ gtk_widget_show (de->sheet_bin[2]);
+ sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[2]));
+ gtk_sheet_hide_column_titles (GTK_SHEET (sheet));
+ g_object_set (de->sheet_bin[2], "vscrollbar-policy", GTK_POLICY_NEVER, NULL);
+ g_object_set (de->sheet_bin[2], "hscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
+ vadj1 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[2]));
+
+ init_sheet (de, 3, hadj1, vadj1, de->vaxis[1], de->haxis);
+ gtk_widget_show (de->sheet_bin[3]);
+ sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[3]));
+ gtk_sheet_hide_column_titles (GTK_SHEET (sheet));
+ gtk_sheet_hide_row_titles (GTK_SHEET (sheet));
+ g_object_set (de->sheet_bin[3], "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
+ g_object_set (de->sheet_bin[3], "hscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
+
+ gtk_xpaned_pack_top_left (GTK_XPANED (de->paned), de->sheet_bin[0], TRUE, TRUE);
+ gtk_xpaned_pack_top_right (GTK_XPANED (de->paned), de->sheet_bin[1], TRUE, TRUE);
+ gtk_xpaned_pack_bottom_left (GTK_XPANED (de->paned), de->sheet_bin[2], TRUE, TRUE);
+ gtk_xpaned_pack_bottom_right (GTK_XPANED (de->paned), de->sheet_bin[3], TRUE, TRUE);
+
+ gtk_xpaned_set_position_y (GTK_XPANED (de->paned), 150);
+ gtk_xpaned_set_position_x (GTK_XPANED (de->paned), 350);
+}
+
+
static void
psppire_data_editor_init (PsppireDataEditor *de)
{
- GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
- GtkWidget *sw_ds = gtk_scrolled_window_new (NULL, NULL);
GtkWidget *sw_vs = gtk_scrolled_window_new (NULL, NULL);
+ init_data_sheet (de);
- de->data_sheet = gtk_sheet_new (NULL, NULL, NULL);
+ de->data_vbox = gtk_vbox_new (FALSE, 0);
de->var_sheet = psppire_var_sheet_new ();
g_object_set (de, "tab-pos", GTK_POS_BOTTOM, NULL);
gtk_widget_show_all (sw_vs);
- gtk_container_add (GTK_CONTAINER (sw_ds), de->data_sheet);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), sw_ds, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (de->data_vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (de->data_vbox), de->paned, TRUE, TRUE, 0);
+
- gtk_widget_show_all (vbox);
+ psppire_data_editor_remove_split (de);
- gtk_notebook_append_page (GTK_NOTEBOOK (de), vbox,
+ gtk_widget_show_all (de->data_vbox);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (de), de->data_vbox,
gtk_label_new_with_mnemonic (_("Data View")));
gtk_notebook_append_page (GTK_NOTEBOOK (de), sw_vs,
gtk_label_new_with_mnemonic (_("Variable View")));
- g_signal_connect (de->data_sheet, "activate",
+ g_signal_connect (de->data_sheet[0], "activate",
G_CALLBACK (update_data_ref_entry),
de);
de);
- g_signal_connect_swapped (de->data_sheet,
+ g_signal_connect_swapped (de->data_sheet[0],
"double-click-column",
G_CALLBACK (on_data_column_clicked),
de);
G_CALLBACK (on_var_row_clicked),
de);
- g_signal_connect_swapped (de->data_sheet, "activate",
+ g_signal_connect_swapped (de->data_sheet[0], "activate",
G_CALLBACK (on_activate),
de);
- g_signal_connect_swapped (de->data_sheet, "deactivate",
- G_CALLBACK (on_deactivate),
- de);
-
- g_signal_connect_swapped (de->data_sheet, "select-range",
+ g_signal_connect_swapped (de->data_sheet[0], "select-range",
G_CALLBACK (on_select_range),
de);
- g_signal_connect (de->data_sheet, "select-row",
+ g_signal_connect (de->data_sheet[0], "select-row",
G_CALLBACK (on_select_row), de);
- g_signal_connect (de->data_sheet, "select-column",
+ g_signal_connect (de->data_sheet[0], "select-column",
G_CALLBACK (on_select_variable), de);
g_signal_connect (de, "map", G_CALLBACK (on_map), NULL);
+
+
+ // gtk_sheet_hide_column_titles (de->var_sheet);
+ // gtk_sheet_hide_row_titles (de->data_sheet);
+
+
de->dispose_has_run = FALSE;
}
psppire_data_editor_new (PsppireVarStore *var_store,
PsppireDataStore *data_store)
{
- GtkWidget *widget;
+ return g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
+ "var-store", var_store,
+ "data-store", data_store,
+ NULL);
+}
+
+
+static void
+psppire_data_editor_remove_split (PsppireDataEditor *de)
+{
+ if ( !de->split ) return;
+ de->split = FALSE;
+
+ g_object_ref (de->sheet_bin[0]);
+ gtk_container_remove (GTK_CONTAINER (de->paned), de->sheet_bin[0]);
+
+ g_object_ref (de->paned);
+ gtk_container_remove (GTK_CONTAINER (de->data_vbox), de->paned);
+
+ gtk_box_pack_start (GTK_BOX (de->data_vbox), de->sheet_bin[0],
+ TRUE, TRUE, 0);
+
+ g_object_unref (de->sheet_bin[0]);
+
+ g_object_set (de->sheet_bin[0], "vscrollbar-policy",
+ GTK_POLICY_ALWAYS, NULL);
+
+ g_object_set (de->sheet_bin[0], "hscrollbar-policy",
+ GTK_POLICY_ALWAYS, NULL);
+}
+
+
+static void
+psppire_data_editor_set_split (PsppireDataEditor *de)
+{
+ if ( de->split ) return;
+ de->split = TRUE;
+
+ g_object_ref (de->sheet_bin[0]);
+ gtk_container_remove (GTK_CONTAINER (de->data_vbox), de->sheet_bin[0]);
- widget = g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
- "var-store", var_store,
- "data-store", data_store,
- NULL);
+ gtk_xpaned_pack_top_left (GTK_XPANED (de->paned), de->sheet_bin [0],
+ TRUE, TRUE);
- return widget;
+ gtk_box_pack_start (GTK_BOX (de->data_vbox), de->paned,
+ TRUE, TRUE, 0);
+
+ g_object_unref (de->paned);
+
+ g_object_set (de->sheet_bin[0], "vscrollbar-policy",
+ GTK_POLICY_NEVER, NULL);
+
+ g_object_set (de->sheet_bin[0], "hscrollbar-policy",
+ GTK_POLICY_NEVER, NULL);
+}
+
+void
+psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
+{
+ if (split )
+ psppire_data_editor_set_split (de);
+ else
+ psppire_data_editor_remove_split (de);
+
+ gtk_widget_show_all (de->data_vbox);
}
static void data_sheet_set_clip (GtkSheet *sheet);
void
psppire_data_editor_clip_copy (PsppireDataEditor *de)
{
- data_sheet_set_clip (GTK_SHEET (de->data_sheet));
+ data_sheet_set_clip (GTK_SHEET (de->data_sheet[0]));
}
void
GtkSheetRange range;
PsppireDataStore *ds = de->data_store;
- data_sheet_set_clip (GTK_SHEET (de->data_sheet));
+ data_sheet_set_clip (GTK_SHEET (de->data_sheet[0]));
/* Now blank all the cells */
- gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range);
+ gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range);
/* If nothing selected, then use active cell */
if ( range.row0 < 0 || range.col0 < 0 )
{
gint row, col;
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col);
range.row0 = range.rowi = row;
range.col0 = range.coli = col;
}
/* and remove the selection */
- gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet));
+ gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0]));
}
/* Popup menu related stuff */
static void
-popup_variable_menu (GtkSheet *sheet, gint column,
+popup_variable_column_menu (GtkSheet *sheet, gint column,
GdkEventButton *event, gpointer data)
{
GtkMenu *menu = GTK_MENU (data);
}
+static void
+popup_variable_row_menu (GtkSheet *sheet, gint row,
+ GdkEventButton *event, gpointer data)
+{
+ GtkMenu *menu = GTK_MENU (data);
+
+ PsppireVarStore *var_store =
+ PSPPIRE_VAR_STORE (gtk_sheet_get_model (sheet));
+
+ const struct variable *v =
+ psppire_dict_get_variable (var_store->dict, row);
+
+ if ( v && event->button == 3)
+ {
+ gtk_sheet_select_row (sheet, row);
+
+ gtk_menu_popup (menu,
+ NULL, NULL, NULL, NULL,
+ event->button, event->time);
+ }
+}
+
+
static void
popup_cases_menu (GtkSheet *sheet, gint row,
GdkEventButton *event, gpointer data)
psppire_data_editor_sort_ascending (PsppireDataEditor *de)
{
GtkSheetRange range;
- gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet), &range);
+ gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet[0]), &range);
do_sort (de->data_store, range.col0, FALSE);
}
psppire_data_editor_sort_descending (PsppireDataEditor *de)
{
GtkSheetRange range;
- gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet), &range);
+ gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet[0]), &range);
do_sort (de->data_store, range.col0, TRUE);
}
void
psppire_data_editor_insert_variable (PsppireDataEditor *de)
{
- glong posn = -1;
-
- if ( de->data_sheet->state == GTK_SHEET_COLUMN_SELECTED )
- posn = GTK_SHEET (de->data_sheet)->range.col0;
- else
- posn = GTK_SHEET (de->data_sheet)->active_cell.col;
+ glong posn = 0;
- if ( posn == -1 ) posn = 0;
+ switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
+ {
+ case PSPPIRE_DATA_EDITOR_DATA_VIEW:
+ if ( de->data_sheet[0]->state == GTK_SHEET_COLUMN_SELECTED )
+ posn = GTK_SHEET (de->data_sheet[0])->range.col0;
+ else
+ posn = GTK_SHEET (de->data_sheet[0])->active_cell.col;
+ break;
+ case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
+ if ( de->var_sheet->state == GTK_SHEET_ROW_SELECTED )
+ posn = GTK_SHEET (de->var_sheet)->range.row0;
+ else
+ posn = GTK_SHEET (de->var_sheet)->active_cell.row;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ };
psppire_dict_insert_variable (de->data_store->dict, posn, NULL);
}
{
glong posn = -1;
- if ( de->data_sheet->state == GTK_SHEET_ROW_SELECTED )
- posn = GTK_SHEET (de->data_sheet)->range.row0;
+ if ( de->data_sheet[0]->state == GTK_SHEET_ROW_SELECTED )
+ posn = GTK_SHEET (de->data_sheet[0])->range.row0;
else
- posn = GTK_SHEET (de->data_sheet)->active_cell.row;
+ posn = GTK_SHEET (de->data_sheet[0])->active_cell.row;
if ( posn == -1 ) posn = 0;
void
psppire_data_editor_delete_cases (PsppireDataEditor *de)
{
- gint first = GTK_SHEET (de->data_sheet)->range.row0;
- gint n = GTK_SHEET (de->data_sheet)->range.rowi - first + 1;
+ gint first = GTK_SHEET (de->data_sheet[0])->range.row0;
+ gint n = GTK_SHEET (de->data_sheet[0])->range.rowi - first + 1;
psppire_data_store_delete_cases (de->data_store, first, n);
- gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet));
+ gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0]));
}
/* Delete the variables currently selected in the
switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
{
case PSPPIRE_DATA_EDITOR_DATA_VIEW:
- first = GTK_SHEET (de->data_sheet)->range.col0;
- n = GTK_SHEET (de->data_sheet)->range.coli - first + 1;
+ first = GTK_SHEET (de->data_sheet[0])->range.col0;
+ n = GTK_SHEET (de->data_sheet[0])->range.coli - first + 1;
break;
case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
first = GTK_SHEET (de->var_sheet)->range.row0;
psppire_dict_delete_variables (de->var_store->dict, first, n);
- gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet));
+ gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0]));
gtk_sheet_unselect_range (GTK_SHEET (de->var_sheet));
}
psppire_data_editor_show_grid (PsppireDataEditor *de, gboolean grid_visible)
{
gtk_sheet_show_grid (GTK_SHEET (de->var_sheet), grid_visible);
- gtk_sheet_show_grid (GTK_SHEET (de->data_sheet), grid_visible);
+ gtk_sheet_show_grid (GTK_SHEET (de->data_sheet[0]), grid_visible);
+}
+
+
+static void
+set_font (GtkWidget *w, gpointer data)
+{
+ PangoFontDescription *font_desc = data;
+ GtkRcStyle *style = gtk_widget_get_modifier_style (w);
+
+ pango_font_description_free (style->font_desc);
+ style->font_desc = pango_font_description_copy (font_desc);
+
+ gtk_widget_modify_style (w, style);
+
+ if ( GTK_IS_CONTAINER (w))
+ gtk_container_foreach (GTK_CONTAINER (w), set_font, font_desc);
}
void
psppire_data_editor_set_font (PsppireDataEditor *de, PangoFontDescription *font_desc)
{
- psppire_data_store_set_font (de->data_store, font_desc);
- psppire_var_store_set_font (de->var_store, font_desc);
+ set_font (GTK_WIDGET (de), font_desc);
+ gtk_container_foreach (GTK_CONTAINER (de), set_font, font_desc);
}
g_signal_emit (de, data_editor_signals[DATA_SELECTION_CHANGED], 0, data_selected);
}
+
static void
on_activate (PsppireDataEditor *de)
{
gint row, col;
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col);
+
if ( row < psppire_data_store_get_case_count (de->data_store)
&&
}
-static void
-on_deactivate (PsppireDataEditor *de)
-{
- emit_selected_signal (de);
-}
-
static void
on_select_range (PsppireDataEditor *de)
{
GtkSheetRange range;
- gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range);
+ gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range);
if ( range.rowi < psppire_data_store_get_case_count (de->data_store)
&&
static gboolean
-on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p, gint pagenum, gpointer data)
+on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p,
+ gint pagenum, gpointer data)
{
if ( pagenum != PSPPIRE_DATA_EDITOR_DATA_VIEW )
{
if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (de)) != PSPPIRE_DATA_EDITOR_DATA_VIEW)
return FALSE;
- gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col);
+ gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col);
if ( row >= psppire_data_store_get_case_count (de->data_store)
||
return FALSE;
}
- gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range);
+ gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range);
if ( range.rowi >= psppire_data_store_get_case_count (de->data_store)
||
{
struct ccase old;
- if (psppire_case_file_get_case (ds->case_file, i, &old))
+ if (psppire_data_store_get_case (ds, i, &old))
{
struct ccase new;
c = (char *) sd->data;
/* Paste text to selected position */
- gtk_sheet_get_active_cell (GTK_SHEET (data_editor->data_sheet),
+ gtk_sheet_get_active_cell (GTK_SHEET (data_editor->data_sheet[0]),
&row, &column);
g_return_if_fail (row >= 0);
g_signal_emit (de, data_editor_signals[DATA_AVAILABLE_CHANGED], 0,
compatible_target);
}
+
+
#include <glib-object.h>
#include <gtk/gtknotebook.h>
+#include <lib/gtksheet/psppire-axis-impl.h>
#include "psppire-var-store.h"
#include "psppire-data-store.h"
gboolean dispose_has_run;
GtkWidget *cell_ref_entry;
GtkWidget *datum_entry;
- GtkWidget *data_sheet;
GtkWidget *var_sheet;
PsppireDataStore *data_store;
PsppireVarStore *var_store;
+
+ GtkWidget *sheet_bin[4];
+ GtkWidget *data_sheet[4];
+
+ GtkWidget *data_vbox;
+
+ GtkWidget *paned;
+ gboolean split;
+
+ PsppireAxisImpl *vaxis[2];
+
+ /* There's only one horizontal axis, since the
+ column widths are parameters of the variables */
+ PsppireAxisImpl *haxis;
};
void psppire_data_editor_delete_cases (PsppireDataEditor *);
void psppire_data_editor_set_font (PsppireDataEditor *, PangoFontDescription *);
void psppire_data_editor_delete_cases (PsppireDataEditor *);
-
+void psppire_data_editor_split_window (PsppireDataEditor *, gboolean );
G_END_DECLS
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2006 Free Software Foundation
+ Copyright (C) 2006, 2008 Free Software Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <data/variable.h>
#include <gtksheet/gsheetmodel.h>
-#include <gtksheet/gsheet-column-iface.h>
-#include <gtksheet/gsheet-row-iface.h>
+#include <gtksheet/psppire-marshal.h>
#include <pango/pango-context.h>
#include "psppire-data-store.h"
-#include "psppire-case-file.h"
#include "helper.h"
#include <data/dictionary.h>
#include <data/data-in.h>
#include <data/format.h>
+#include <math/sort.h>
+
+#include "xalloc.h"
+#include "xmalloca.h"
+
+
static void psppire_data_store_init (PsppireDataStore *data_store);
static void psppire_data_store_class_init (PsppireDataStoreClass *class);
static void psppire_data_store_sheet_model_init (GSheetModelIface *iface);
-static void psppire_data_store_sheet_column_init (GSheetColumnIface *iface);
-static void psppire_data_store_sheet_row_init (GSheetRowIface *iface);
static void psppire_data_store_finalize (GObject *object);
static void psppire_data_store_dispose (GObject *object);
glong row, glong column);
-#define MIN_COLUMNS 10
+static gboolean psppire_data_store_insert_case (PsppireDataStore *ds,
+ struct ccase *cc,
+ casenumber posn);
+
+
+static gboolean psppire_data_store_data_in (PsppireDataStore *ds,
+ casenumber casenum, gint idx,
+ struct substring input,
+ const struct fmt_spec *fmt);
+
-#define TRAILING_ROWS 10
static GObjectClass *parent_class = NULL;
-enum {FONT_CHANGED,
- n_SIGNALS};
+enum
+ {
+ BACKEND_CHANGED,
+ CASES_DELETED,
+ CASE_INSERTED,
+ CASE_CHANGED,
+ n_SIGNALS
+ };
static guint signals [n_SIGNALS];
NULL
};
- static const GInterfaceInfo sheet_column_info =
- {
- (GInterfaceInitFunc) psppire_data_store_sheet_column_init,
- NULL,
- NULL
- };
-
- static const GInterfaceInfo sheet_row_info =
- {
- (GInterfaceInitFunc) psppire_data_store_sheet_row_init,
- NULL,
- NULL
- };
-
- data_store_type = g_type_register_static (G_TYPE_OBJECT, "PsppireDataStore",
+ data_store_type = g_type_register_static (G_TYPE_OBJECT,
+ "PsppireDataStore",
&data_store_info, 0);
g_type_add_interface_static (data_store_type,
G_TYPE_SHEET_MODEL,
&sheet_model_info);
- g_type_add_interface_static (data_store_type,
- G_TYPE_SHEET_COLUMN,
- &sheet_column_info);
-
- g_type_add_interface_static (data_store_type,
- G_TYPE_SHEET_ROW,
- &sheet_row_info);
}
return data_store_type;
object_class->finalize = psppire_data_store_finalize;
object_class->dispose = psppire_data_store_dispose;
- signals [FONT_CHANGED] =
- g_signal_new ("font_changed",
+ signals [BACKEND_CHANGED] =
+ g_signal_new ("backend-changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_FIRST,
0,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+
+ signals [CASE_INSERTED] =
+ g_signal_new ("case-inserted",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+
+ signals [CASE_CHANGED] =
+ g_signal_new ("case-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ signals [CASES_DELETED] =
+ g_signal_new ("cases-deleted",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ psppire_marshal_VOID__INT_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
}
+static gboolean
+psppire_data_store_insert_values (PsppireDataStore *ds,
+ gint n_values, gint where);
+
+static union value *
+psppire_data_store_get_value (const PsppireDataStore *ds,
+ casenumber casenum, size_t idx,
+ union value *value, int width);
+
+
+static gboolean
+psppire_data_store_set_value (PsppireDataStore *ds, casenumber casenum,
+ gint idx, union value *v, gint width);
+
+
+
+
static glong
psppire_data_store_get_var_count (const GSheetModel *model)
{
casenumber
psppire_data_store_get_case_count (const PsppireDataStore *store)
{
- return psppire_case_file_get_case_count (store->case_file);
+ return datasheet_get_row_cnt (store->datasheet);
}
size_t
return psppire_dict_get_value_cnt (store->dict);
}
-casenumber
+static casenumber
psppire_data_store_get_case_count_wrapper (const GSheetModel *model)
{
const PsppireDataStore *store = PSPPIRE_DATA_STORE (model);
psppire_data_store_init (PsppireDataStore *data_store)
{
data_store->dict = 0;
- data_store->case_file = NULL;
- data_store->width_of_m = 10;
+ data_store->datasheet = NULL;
data_store->dispose_has_run = FALSE;
}
-const PangoFontDescription *
-psppire_data_store_get_font_desc (const GSheetModel *model,
- glong row, glong column)
-{
- PsppireDataStore *store = PSPPIRE_DATA_STORE (model);
-
- return store->font_desc;
-}
-
static inline gchar *
psppire_data_store_get_string_wrapper (const GSheetModel *model, glong row,
glong column)
+static gchar * get_column_subtitle (const GSheetModel *model, gint col);
+static gchar * get_column_button_label (const GSheetModel *model, gint col);
+static gboolean get_column_sensitivity (const GSheetModel *model, gint col);
+static GtkJustification get_column_justification (const GSheetModel *model, gint col);
+
+static gchar * get_row_button_label (const GSheetModel *model, gint row);
+static gboolean get_row_sensitivity (const GSheetModel *model, gint row);
+
static void
psppire_data_store_sheet_model_init (GSheetModelIface *iface)
iface->set_string = psppire_data_store_set_string_wrapper;
iface->clear_datum = psppire_data_store_clear_datum;
iface->is_editable = NULL;
- iface->is_visible = NULL;
iface->get_foreground = NULL;
iface->get_background = NULL;
- iface->get_font_desc = psppire_data_store_get_font_desc;
- iface->get_cell_border = NULL;
iface->get_column_count = psppire_data_store_get_var_count;
iface->get_row_count = psppire_data_store_get_case_count_wrapper;
-}
-static
-gboolean always_true ()
-{
- return TRUE;
-}
+ iface->get_column_subtitle = get_column_subtitle;
+ iface->get_column_title = get_column_button_label;
+ iface->get_column_sensitivity = get_column_sensitivity;
+ iface->get_column_justification = get_column_justification;
-
-static void
-delete_cases_callback (GtkWidget *w,
- casenumber first, casenumber n_cases, gpointer data)
-{
- PsppireDataStore *store ;
-
- g_return_if_fail (data);
-
- store = PSPPIRE_DATA_STORE (data);
-
- g_assert (first >= 0);
-
- g_sheet_model_rows_deleted (G_SHEET_MODEL (store), first, n_cases);
-}
-
-
-static void
-insert_case_callback (GtkWidget *w, casenumber casenum, gpointer data)
-{
- PsppireDataStore *store ;
-
- g_return_if_fail (data);
-
- store = PSPPIRE_DATA_STORE (data);
-
- g_sheet_model_range_changed (G_SHEET_MODEL (store),
- casenum, -1,
- psppire_case_file_get_case_count (store->case_file),
- -1);
-
- g_sheet_model_rows_inserted (G_SHEET_MODEL (store), casenum, 1);
-}
-
-
-static void
-changed_case_callback (GtkWidget *w, gint casenum, gpointer data)
-{
- PsppireDataStore *store ;
- g_return_if_fail (data);
-
- store = PSPPIRE_DATA_STORE (data);
-
- g_sheet_model_range_changed (G_SHEET_MODEL (store),
- casenum, -1,
- casenum, -1);
+ iface->get_row_title = get_row_button_label;
+ iface->get_row_sensitivity = get_row_sensitivity;
}
{
PsppireDataStore *store = PSPPIRE_DATA_STORE (data);
+
g_sheet_model_columns_deleted (G_SHEET_MODEL (store), dict_index, 1);
+#if AXIS_TRANSITION
+
g_sheet_column_columns_changed (G_SHEET_COLUMN (store),
dict_index, -1);
+#endif
}
+
static void
variable_changed_callback (GObject *obj, gint var_num, gpointer data)
{
PsppireDataStore *store = PSPPIRE_DATA_STORE (data);
+#if AXIS_TRANSITION
g_sheet_column_columns_changed (G_SHEET_COLUMN (store),
var_num, 1);
g_sheet_model_range_changed (G_SHEET_MODEL (store),
-1, var_num,
-1, var_num);
+#endif
}
static void
posn = 0;
}
- psppire_case_file_insert_values (store->case_file, 1, posn);
+ psppire_data_store_insert_values (store, 1, posn);
+
+#if AXIS_TRANSITION
g_sheet_column_columns_changed (G_SHEET_COLUMN (store),
var_num, 1);
+#endif
g_sheet_model_columns_inserted (G_SHEET_MODEL (store), var_num, 1);
}
const gint new_val_width = value_cnt_from_width (var_get_width (v));
if ( adjustment > 0 )
- psppire_case_file_insert_values (store->case_file, adjustment,
+ psppire_data_store_insert_values (store, adjustment,
new_val_width - adjustment +
var_get_case_index(v));
}
return retval;
}
-
void
-psppire_data_store_set_case_file (PsppireDataStore *ds,
- PsppireCaseFile *cf)
+psppire_data_store_set_reader (PsppireDataStore *ds,
+ struct casereader *reader)
{
gint i;
- if ( ds->case_file) g_object_unref (ds->case_file);
+ if ( ds->datasheet)
+ datasheet_destroy (ds->datasheet);
- ds->case_file = cf;
+ ds->datasheet = datasheet_create (reader);
g_sheet_model_range_changed (G_SHEET_MODEL (ds),
-1, -1, -1, -1);
- for (i = 0 ; i < n_cf_signals ; ++i )
- {
- if ( ds->cf_handler_id [i] > 0 )
- g_signal_handler_disconnect (ds->case_file,
- ds->cf_handler_id[i]);
- }
-
-
if ( ds->dict )
for (i = 0 ; i < n_dict_signals; ++i )
{
}
}
- ds->cf_handler_id [CASES_DELETED] =
- g_signal_connect (ds->case_file, "cases-deleted",
- G_CALLBACK (delete_cases_callback),
- ds);
-
- ds->cf_handler_id [CASE_INSERTED] =
- g_signal_connect (ds->case_file, "case-inserted",
- G_CALLBACK (insert_case_callback),
- ds);
-
- ds->cf_handler_id [CASE_CHANGED] =
- g_signal_connect (ds->case_file, "case-changed",
- G_CALLBACK (changed_case_callback),
- ds);
+ g_signal_emit (ds, signals[BACKEND_CHANGED], 0);
}
/* The entire model has changed */
g_sheet_model_range_changed (G_SHEET_MODEL (data_store), -1, -1, -1, -1);
+#if AXIS_TRANSITION
g_sheet_column_columns_changed (G_SHEET_COLUMN (data_store), 0, -1);
-
+#endif
if ( data_store->dict )
for (i = 0 ; i < n_dict_signals; ++i )
if (ds->dispose_has_run)
return;
- if (ds->case_file) g_object_unref (ds->case_file);
+ if (ds->datasheet)
+ {
+ datasheet_destroy (ds->datasheet);
+ ds->datasheet = NULL;
+ }
/* must chain up */
(* parent_class->dispose) (object);
}
-gboolean
-psppire_data_store_delete_cases (PsppireDataStore *ds,
- casenumber first, casenumber count)
-{
- g_return_val_if_fail (ds, FALSE);
-
- return psppire_case_file_delete_cases (ds->case_file, count, first);
-}
-
-
/* Insert a blank case before POSN */
gboolean
struct ccase cc;
g_return_val_if_fail (ds, FALSE);
- val_cnt = datasheet_get_column_cnt (ds->case_file->datasheet) ;
+ val_cnt = datasheet_get_column_cnt (ds->datasheet) ;
g_return_val_if_fail (val_cnt > 0, FALSE);
case_data_rw (&cc, pv)->f = SYSMIS;
}
- result = psppire_case_file_insert_case (ds->case_file, &cc, posn);
+ result = psppire_data_store_insert_case (ds, &cc, posn);
case_destroy (&cc);
GString *s;
g_return_val_if_fail (store->dict, NULL);
- g_return_val_if_fail (store->case_file, NULL);
+ g_return_val_if_fail (store->datasheet, NULL);
if (column >= psppire_dict_get_var_cnt (store->dict))
return NULL;
- if ( row >= psppire_case_file_get_case_count (store->case_file))
+ if ( row >= psppire_data_store_get_case_count (store))
return NULL;
pv = psppire_dict_get_variable (store->dict, column);
g_assert (idx >= 0);
- v = psppire_case_file_get_value (store->case_file, row, idx, NULL,
+ v = psppire_data_store_get_value (store, row, idx, NULL,
var_get_width (pv));
g_return_val_if_fail (v, NULL);
else
memcpy (v.s, "", MAX_SHORT_STRING);
- psppire_case_file_set_value (store->case_file, row, index, &v,
- var_get_width (pv));
+ psppire_data_store_set_value (store, row, index, &v,
+ var_get_width (pv));
+
+ g_sheet_model_range_changed (model, row, col, row, col);
return TRUE;
}
if (row == n_cases)
psppire_data_store_insert_new_case (store, row);
- psppire_case_file_data_in (store->case_file, row,
- var_get_case_index (pv), ss_cstr (text),
- var_get_write_format (pv));
+ psppire_data_store_data_in (store, row,
+ var_get_case_index (pv), ss_cstr (text),
+ var_get_write_format (pv));
+
+ g_sheet_model_range_changed (G_SHEET_MODEL (store), row, col, row, col);
return TRUE;
}
-void
-psppire_data_store_set_font (PsppireDataStore *store,
- const PangoFontDescription *fd)
-{
- g_return_if_fail (store);
- g_return_if_fail (PSPPIRE_IS_DATA_STORE (store));
-
- store->font_desc = fd;
-#if 0
- store->width_of_m = calc_m_width (fd);
-#endif
- g_signal_emit (store, signals [FONT_CHANGED], 0);
-
-
- g_sheet_model_range_changed (G_SHEET_MODEL (store),
- -1, -1, -1, -1);
-}
-
void
psppire_data_store_show_labels (PsppireDataStore *store, gboolean show_labels)
void
-psppire_data_store_clear (PsppireDataStore *data_store)
+psppire_data_store_clear (PsppireDataStore *ds)
{
- psppire_case_file_clear (data_store->case_file);
+ datasheet_destroy (ds->datasheet);
+ ds->datasheet = NULL;
- psppire_dict_clear (data_store->dict);
+ psppire_dict_clear (ds->dict);
+
+ g_signal_emit (ds, signals [CASES_DELETED], 0, 0, -1);
}
int i;
struct casereader *reader ;
- for (i = 0 ; i < n_cf_signals ; ++i )
- {
- g_signal_handler_disconnect (ds->case_file, ds->cf_handler_id[i]);
- ds->cf_handler_id[i] = 0 ;
- }
-
if ( ds->dict )
for (i = 0 ; i < n_dict_signals; ++i )
{
ds->dict_handler_id[i]);
}
- reader = psppire_case_file_make_reader (ds->case_file);
+ reader = datasheet_make_reader (ds->datasheet);
+
+ /* We must not reference this again */
+ ds->datasheet = NULL;
return reader;
}
/* Column related funcs */
-static glong
-geometry_get_column_count (const GSheetColumn *geom)
-{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
- return MAX (MIN_COLUMNS, psppire_dict_get_var_cnt (ds->dict));
-}
+static const gchar null_var_name[]=N_("var");
+\f
+/* Row related funcs */
-static gint
-geometry_get_width (const GSheetColumn *geom, glong unit)
+static gchar *
+get_row_button_label (const GSheetModel *model, gint unit)
{
- const struct variable *pv ;
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ gchar *s = g_strdup_printf (_("%d"), unit + FIRST_CASE_NUMBER);
- if ( unit >= psppire_dict_get_var_cnt (ds->dict) )
- return ds->width_of_m * 8 ;
+ gchar *text = pspp_locale_to_utf8 (s, -1, 0);
- pv = psppire_dict_get_variable (ds->dict, unit);
-
- if ( pv == NULL )
- return ds->width_of_m * 8 ;
+ g_free (s);
- return ds->width_of_m * var_get_display_width (pv);
+ return text;
}
-static void
-geometry_set_width (GSheetColumn *geom, glong unit, gint width)
-{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
- struct variable *pv = psppire_dict_get_variable (ds->dict, unit);
+static gboolean
+get_row_sensitivity (const GSheetModel *model, gint unit)
+{
+ PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- var_set_display_width (pv, width / ds->width_of_m );
+ return (unit < psppire_data_store_get_case_count (ds));
}
+\f
-static GtkJustification
-geometry_get_justification (const GSheetColumn *geom, glong unit)
-{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
- const struct variable *pv ;
+/* Column related stuff */
+static gchar *
+get_column_subtitle (const GSheetModel *model, gint col)
+{
+ gchar *text;
+ const struct variable *v ;
+ PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- if ( unit >= psppire_dict_get_var_cnt (ds->dict) )
- return GTK_JUSTIFY_LEFT;
+ if ( col >= psppire_dict_get_var_cnt (ds->dict) )
+ return NULL;
- pv = psppire_dict_get_variable (ds->dict, unit);
+ v = psppire_dict_get_variable (ds->dict, col);
- return (var_get_alignment (pv) == ALIGN_LEFT ? GTK_JUSTIFY_LEFT
- : var_get_alignment (pv) == ALIGN_RIGHT ? GTK_JUSTIFY_RIGHT
- : GTK_JUSTIFY_CENTER);
-}
+ if ( ! var_has_label (v))
+ return NULL;
+ text = pspp_locale_to_utf8 (var_get_label (v), -1, 0);
-static const gchar null_var_name[]=N_("var");
+ return text;
+}
static gchar *
-geometry_get_column_button_label (const GSheetColumn *geom, glong unit)
+get_column_button_label (const GSheetModel *model, gint col)
{
gchar *text;
struct variable *pv ;
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- if ( unit >= psppire_dict_get_var_cnt (ds->dict) )
+ if ( col >= psppire_dict_get_var_cnt (ds->dict) )
return g_locale_to_utf8 (null_var_name, -1, 0, 0, 0);
- pv = psppire_dict_get_variable (ds->dict, unit);
+ pv = psppire_dict_get_variable (ds->dict, col);
text = pspp_locale_to_utf8 (var_get_name (pv), -1, 0);
return text;
}
-
-static gchar *
-geometry_get_column_subtitle (const GSheetColumn *geom, glong unit)
+static gboolean
+get_column_sensitivity (const GSheetModel *model, gint col)
{
- gchar *text;
- const struct variable *v ;
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- if ( unit >= psppire_dict_get_var_cnt (ds->dict) )
- return NULL;
+ return (col < psppire_dict_get_var_cnt (ds->dict));
+}
- v = psppire_dict_get_variable (ds->dict, unit);
- if ( ! var_has_label (v))
- return NULL;
- text = pspp_locale_to_utf8 (var_get_label (v), -1, 0);
+static GtkJustification
+get_column_justification (const GSheetModel *model, gint col)
+{
+ PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
+ const struct variable *pv ;
- return text;
+ if ( col >= psppire_dict_get_var_cnt (ds->dict) )
+ return GTK_JUSTIFY_LEFT;
+
+ pv = psppire_dict_get_variable (ds->dict, col);
+
+ return (var_get_alignment (pv) == ALIGN_LEFT ? GTK_JUSTIFY_LEFT
+ : var_get_alignment (pv) == ALIGN_RIGHT ? GTK_JUSTIFY_RIGHT
+ : GTK_JUSTIFY_CENTER);
}
-static gboolean
-geometry_get_sensitivity (const GSheetColumn *geom, glong unit)
+
+\f
+
+
+/* Fills C with the CASENUMth case.
+ Returns true on success, false otherwise.
+ */
+gboolean
+psppire_data_store_get_case (const PsppireDataStore *ds,
+ casenumber casenum,
+ struct ccase *c)
{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ g_return_val_if_fail (ds, FALSE);
+ g_return_val_if_fail (ds->datasheet, FALSE);
- return (unit < psppire_dict_get_var_cnt (ds->dict));
+ return datasheet_get_row (ds->datasheet, casenum, c);
}
-static void
-psppire_data_store_sheet_column_init (GSheetColumnIface *iface)
+gboolean
+psppire_data_store_delete_cases (PsppireDataStore *ds, casenumber first,
+ casenumber n_cases)
{
- iface->get_column_count = geometry_get_column_count;
- iface->get_width = geometry_get_width;
- iface->set_width = geometry_set_width;
- iface->get_visibility = always_true;
- iface->get_sensitivity = geometry_get_sensitivity;
- iface->get_justification = geometry_get_justification;
- iface->get_button_label = geometry_get_column_button_label;
- iface->get_subtitle = geometry_get_column_subtitle;
-}
+ g_return_val_if_fail (ds, FALSE);
+ g_return_val_if_fail (ds->datasheet, FALSE);
+ g_return_val_if_fail (first + n_cases <=
+ psppire_data_store_get_case_count (ds), FALSE);
-/* Row related funcs */
-static glong
-geometry_get_row_count (const GSheetRow *geom)
-{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ datasheet_delete_rows (ds->datasheet, first, n_cases);
- return TRAILING_ROWS + psppire_case_file_get_case_count (ds->case_file);
+ g_signal_emit (ds, signals [CASES_DELETED], 0, first, n_cases);
+ g_sheet_model_rows_deleted (G_SHEET_MODEL (ds), first, n_cases);
+
+ return TRUE;
}
-#define ROW_HEIGHT 25
-static gint
-geometry_get_height (const GSheetRow *geom, glong unit)
-{
- return ROW_HEIGHT;
-}
-static guint
-geometry_get_top_ypixel (const GSheetRow *geo, glong row)
+/* Insert case CC into the case file before POSN */
+static gboolean
+psppire_data_store_insert_case (PsppireDataStore *ds,
+ struct ccase *cc,
+ casenumber posn)
{
- return row * ROW_HEIGHT;
+ struct ccase tmp;
+ bool result ;
+
+ g_return_val_if_fail (ds, FALSE);
+ g_return_val_if_fail (ds->datasheet, FALSE);
+
+ case_clone (&tmp, cc);
+ result = datasheet_insert_rows (ds->datasheet, posn, &tmp, 1);
+
+ if ( result )
+ {
+ g_signal_emit (ds, signals [CASE_INSERTED], 0, posn);
+ g_sheet_model_rows_inserted (G_SHEET_MODEL (ds), posn, 1);
+ }
+ else
+ g_warning ("Cannot insert case at position %ld\n", posn);
+
+ return result;
}
-static glong
-geometry_pixel_to_row (const GSheetRow *geo, guint pixel)
+
+/* Copies the IDXth value from case CASENUM into VALUE.
+ If VALUE is null, then memory is allocated is allocated with
+ malloc. Returns the value if successful, NULL on failure. */
+static union value *
+psppire_data_store_get_value (const PsppireDataStore *ds,
+ casenumber casenum, size_t idx,
+ union value *value, int width)
{
- glong row = pixel / ROW_HEIGHT;
+ bool allocated;
+
+ g_return_val_if_fail (ds, false);
+ g_return_val_if_fail (ds->datasheet, false);
- if (row >= geometry_get_row_count (geo))
- row = geometry_get_row_count (geo) - 1;
+ g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), false);
- return row;
+ if (value == NULL)
+ {
+ value = xnmalloc (value_cnt_from_width (width), sizeof *value);
+ allocated = true;
+ }
+ else
+ allocated = false;
+ if (!datasheet_get_value (ds->datasheet, casenum, idx, value, width))
+ {
+ if (allocated)
+ free (value);
+ value = NULL;
+ }
+ return value;
}
+
+/* Set the IDXth value of case C to V.
+ Returns true if successful, false on I/O error. */
static gboolean
-geometry_get_row_sensitivity (const GSheetRow *geom, glong unit)
+psppire_data_store_set_value (PsppireDataStore *ds, casenumber casenum,
+ gint idx, union value *v, gint width)
{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ bool ok;
+ g_return_val_if_fail (ds, FALSE);
+ g_return_val_if_fail (ds->datasheet, FALSE);
+
+ g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), FALSE);
- return (unit < psppire_case_file_get_case_count (ds->case_file));
+ ok = datasheet_put_value (ds->datasheet, casenum, idx, v, width);
+ if (ok)
+ g_signal_emit (ds, signals [CASE_CHANGED], 0, casenum);
+
+ return ok;
}
-static gchar *
-geometry_get_row_button_label (const GSheetRow *geom, glong unit)
+
+
+/* Set the IDXth value of case C using D_IN */
+static gboolean
+psppire_data_store_data_in (PsppireDataStore *ds, casenumber casenum, gint idx,
+ struct substring input, const struct fmt_spec *fmt)
{
- gchar *text;
- gchar *s;
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom);
+ union value *value = NULL;
+ int width;
+ bool ok;
- if ( unit >
- TRAILING_ROWS + psppire_case_file_get_case_count (ds->case_file))
- return 0;
+ g_return_val_if_fail (ds, FALSE);
+ g_return_val_if_fail (ds->datasheet, FALSE);
- s = g_strdup_printf (_("%ld"), unit + FIRST_CASE_NUMBER);
+ g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), FALSE);
- text = pspp_locale_to_utf8 (s, -1, 0);
+ width = fmt_var_width (fmt);
+ value = xmalloca (value_cnt_from_width (width) * sizeof *value);
+ ok = (datasheet_get_value (ds->datasheet, casenum, idx, value, width)
+ && data_in (input, LEGACY_NATIVE, fmt->type, 0, 0, 0, value, width)
+ && datasheet_put_value (ds->datasheet, casenum, idx, value, width));
- g_free (s);
+ freea (value);
- return text;
+ if (ok)
+ g_signal_emit (ds, signals [CASE_CHANGED], 0, casenum);
+
+ return ok;
}
-static void
-psppire_data_store_sheet_row_init (GSheetRowIface *iface)
+/* Resize the cases in the casefile, by inserting N_VALUES into every
+ one of them at the position immediately preceeding WHERE.
+*/
+static gboolean
+psppire_data_store_insert_values (PsppireDataStore *ds,
+ gint n_values, gint where)
{
- iface->get_row_count = geometry_get_row_count;
+ g_return_val_if_fail (ds, FALSE);
+
+ if ( n_values == 0 )
+ return FALSE;
+
+ g_assert (n_values > 0);
- iface->get_height = geometry_get_height;
- iface->set_height = 0;
- iface->get_visibility = always_true;
- iface->get_sensitivity = geometry_get_row_sensitivity;
- iface->top_ypixel = geometry_get_top_ypixel;
- iface->pixel_to_row = geometry_pixel_to_row;
- iface->get_button_label = geometry_get_row_button_label;
+ if ( ! ds->datasheet )
+ ds->datasheet = datasheet_create (NULL);
+
+ {
+ union value *values = xcalloc (n_values, sizeof *values);
+ datasheet_insert_columns (ds->datasheet, values, n_values, where);
+ free (values);
+ }
+
+ return TRUE;
}
#ifndef __PSPPIRE_DATA_STORE_H__
#define __PSPPIRE_DATA_STORE_H__
-#include <gtksheet/gsheetmodel.h>
#include "psppire-dict.h"
-#include "psppire-case-file.h"
#define FIRST_CASE_NUMBER 1
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
#define GTK_TYPE_DATA_STORE (psppire_data_store_get_type ())
struct dictionary;
-enum cf_signal_handler {
- CASES_DELETED,
- CASE_INSERTED,
- CASE_CHANGED,
- n_cf_signals
-};
-
-
enum dict_signal_handler {
VARIABLE_INSERTED,
VARIABLE_CHANGED,
n_dict_signals
};
-void do_this_thing (PsppireDict *, struct dictionary *, void *);
+struct datasheet;
+struct casereader;
struct _PsppireDataStore
{
/*< private >*/
gboolean dispose_has_run ;
PsppireDict *dict;
- PsppireCaseFile *case_file;
- const PangoFontDescription *font_desc;
-
- /* The width of an upper case 'M' rendered in the current font */
- gint width_of_m ;
+ struct datasheet *datasheet;
gboolean show_labels;
- /* Geometry */
- gint margin_width;
-
- gint cf_handler_id [n_cf_signals];
+ // gint cf_handler_id [n_cf_signals];
gint dict_handler_id [n_dict_signals];
};
struct _PsppireDataStoreClass
{
GObjectClass parent_class;
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
};
-inline GType psppire_data_store_get_type (void) G_GNUC_CONST;
+GType psppire_data_store_get_type (void) G_GNUC_CONST;
PsppireDataStore *psppire_data_store_new (PsppireDict *dict);
-void psppire_data_store_set_case_file (PsppireDataStore *data_store,
- PsppireCaseFile *cf);
+
+void psppire_data_store_set_reader (PsppireDataStore *ds,
+ struct casereader *reader);
void psppire_data_store_set_dictionary (PsppireDataStore *data_store,
PsppireDict *dict);
-void psppire_data_store_set_font (PsppireDataStore *store,
- const PangoFontDescription *fd);
-
void psppire_data_store_show_labels (PsppireDataStore *store,
- gboolean show_labels);
+ gboolean show_labels);
void psppire_data_store_clear (PsppireDataStore *data_store);
const gchar *text,
glong row, glong column);
-inline casenumber psppire_data_store_get_case_count (const PsppireDataStore *ds);
+casenumber psppire_data_store_get_case_count (const PsppireDataStore *ds);
size_t psppire_data_store_get_value_count (const PsppireDataStore *ds);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+\f
+
+gboolean psppire_data_store_get_case (const PsppireDataStore *ds,
+ casenumber casenum,
+ struct ccase *c);
+
+
+
+
+G_END_DECLS
#endif /* __PSPPIRE_DATA_STORE_H__ */
#include <stdlib.h>
#include <gtk/gtk.h>
-#include <gtksheet/gtkextra-marshal.h>
+#include <gtksheet/psppire-marshal.h>
#include "psppire-dict.h"
#include <data/dictionary.h>
#include "helper.h"
#include "message-dialog.h"
-/* --- prototypes --- */
-static void psppire_dict_class_init (PsppireDictClass *class);
-static void psppire_dict_init (PsppireDict *dict);
-static void psppire_dict_finalize (GObject *object);
-
-static void dictionary_tree_model_init (GtkTreeModelIface *iface);
-
-
-/* --- variables --- */
-static GObjectClass *parent_class = NULL;
enum {
BACKEND_CHANGED,
VARIABLE_RESIZED,
VARIABLE_INSERTED,
VARIABLE_DELETED,
+ VARIABLE_DISPLAY_WIDTH_CHANGED,
WEIGHT_CHANGED,
FILTER_CHANGED,
n_SIGNALS
};
+
+/* --- prototypes --- */
+static void psppire_dict_class_init (PsppireDictClass *class);
+static void psppire_dict_init (PsppireDict *dict);
+static void psppire_dict_finalize (GObject *object);
+
+static void dictionary_tree_model_init (GtkTreeModelIface *iface);
+
+
+/* --- variables --- */
+static GObjectClass *parent_class = NULL;
+
static guint signals [n_SIGNALS];
/* --- functions --- */
g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL,
&tree_model_info);
-
-
}
return object_type;
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
- marshaller_VOID__INT_INT_INT,
+ psppire_marshal_VOID__INT_INT_INT,
G_TYPE_NONE,
3,
G_TYPE_INT,
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
- gtkextra_VOID__INT_INT,
+ psppire_marshal_VOID__INT_INT,
G_TYPE_NONE,
2,
G_TYPE_INT,
G_TYPE_INT);
+ signals [VARIABLE_DISPLAY_WIDTH_CHANGED] =
+ g_signal_new ("variable-display-width-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
signals [WEIGHT_CHANGED] =
g_signal_new ("weight-changed",
static void
addcb (struct dictionary *d, int idx, void *pd)
{
- g_signal_emit (pd, signals [VARIABLE_INSERTED], 0, idx);
+ PsppireDict *dict = PSPPIRE_DICT (pd);
+
+ if ( ! dict->disable_insert_signal)
+ g_signal_emit (dict, signals [VARIABLE_INSERTED], 0, idx);
}
static void
g_signal_emit (pd, signals [SPLIT_CHANGED], 0);
}
+static void
+variable_display_width_callback (struct dictionary *d, int idx, void *pd)
+{
+ g_signal_emit (pd, signals [VARIABLE_DISPLAY_WIDTH_CHANGED], 0, idx);
+}
+
+
static const struct dict_callbacks gui_callbacks =
{
resize_cb,
weight_changed_callback,
filter_changed_callback,
- split_changed_callback
+ split_changed_callback,
+ variable_display_width_callback
};
static void
psppire_dict_init (PsppireDict *psppire_dict)
{
psppire_dict->stamp = g_random_int ();
+ psppire_dict->disable_insert_signal = FALSE;
}
/**
if ( ! name )
name = auto_generate_var_name (d);
+ d->disable_insert_signal = TRUE;
+
var = dict_create_var (d->dict, name, 0);
dict_reorder_var (d->dict, var, idx);
+
+ d->disable_insert_signal = FALSE;
+
+ g_signal_emit (d, signals[VARIABLE_INSERTED], 0, idx);
}
/* Delete N variables beginning at FIRST */
-/* Return the IDXth variable */
+/* Return the IDXth variable.
+ Will return NULL if IDX exceeds the number of variables in the dictionary.
+ */
struct variable *
psppire_dict_get_variable (const PsppireDict *d, gint idx)
{
#define PSPPIRE_DICT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_DICT, PsppireDictClass))
-
/* --- typedefs & structures --- */
typedef struct _PsppireDict PsppireDict;
typedef struct _PsppireDictClass PsppireDictClass;
GObject parent;
struct dictionary *dict;
+ gboolean disable_insert_signal;
/* For GtkTreeModelIface */
gint stamp;
};
gboolean psppire_dict_check_name (const PsppireDict *dict,
const gchar *name, gboolean report);
-inline gint psppire_dict_get_next_value_idx (const PsppireDict *dict);
+gint psppire_dict_get_next_value_idx (const PsppireDict *dict);
gboolean psppire_dict_rename_var (PsppireDict *dict, struct variable *v,
const gchar *text);
-
/* PSPPIRE - a graphical user interface for PSPP.
Copyright (C) 2008 Free Software Foundation, Inc.
#include <config.h>
#include "psppire-var-sheet.h"
+#include <gtksheet/psppire-axis-impl.h>
#include <glade/glade.h>
#include "helper.h"
-#include <gtksheet/gsheet-hetero-column.h>
+
#include "customentry.h"
#include <data/variable.h>
#include "psppire-var-store.h"
static void psppire_var_sheet_class_init (PsppireVarSheetClass *klass);
static void psppire_var_sheet_init (PsppireVarSheet *vs);
-enum
+enum
{
PSPPIRE_VAR_SHEET_MAY_CREATE_VARS = 1
};
gint width ;
};
-static const struct column_parameters column_def[] = {
- { N_("Name"), 80},
- { N_("Type"), 100},
- { N_("Width"), 57},
- { N_("Decimals"),91},
- { N_("Label"), 95},
- { N_("Values"), 103},
- { N_("Missing"), 95},
- { N_("Columns"), 80},
- { N_("Align"), 69},
- { N_("Measure"), 99},
-};
-
-
#define n_ALIGNMENTS 3
const gchar *const alignments[n_ALIGNMENTS + 1]={
}
-
+/* Moves the focus to a new cell.
+ Returns TRUE iff the move should be disallowed */
static gboolean
traverse_cell_callback (GtkSheet *sheet,
- gint row, gint column,
- gint *new_row, gint *new_column
- )
+ const GtkSheetCell *existing_cell,
+ GtkSheetCell *new_cell)
{
PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (sheet);
PsppireVarStore *var_store = PSPPIRE_VAR_STORE (gtk_sheet_get_model (sheet));
gint n_vars = psppire_var_store_get_var_cnt (var_store);
- if (*new_row >= n_vars && !var_sheet->may_create_vars)
- return FALSE;
+ if (new_cell->row >= n_vars && !var_sheet->may_create_vars)
+ return TRUE;
- if ( row == n_vars && *new_row >= n_vars)
+ if ( existing_cell->row == n_vars && new_cell->row >= n_vars)
{
- GtkEntry *entry = GTK_ENTRY (gtk_sheet_get_entry (sheet));
+ GtkEntry *entry = gtk_sheet_get_entry (sheet);
const gchar *name = gtk_entry_get_text (entry);
if (! psppire_dict_check_name (var_store->dict, name, TRUE))
- return FALSE;
+ return TRUE;
- psppire_dict_insert_variable (var_store->dict, row, name);
+ psppire_dict_insert_variable (var_store->dict, existing_cell->row, name);
- return TRUE;
+ return FALSE;
}
+
/* If the destination cell is outside the current variables, then
automatically create variables for the new rows.
*/
- if ( ((*new_row > n_vars) ||
- (*new_row == n_vars && *new_column != PSPPIRE_VAR_STORE_COL_NAME)) )
+ if ( ((new_cell->row > n_vars) ||
+ (new_cell->row == n_vars &&
+ new_cell->col != PSPPIRE_VAR_STORE_COL_NAME)) )
{
gint i;
- for ( i = n_vars ; i <= *new_row; ++i )
+ for ( i = n_vars ; i <= new_cell->row; ++i )
psppire_dict_insert_variable (var_store->dict, i, NULL);
}
- return TRUE;
+ return FALSE;
}
/*
- Callback whenever the pointer leaves a cell on the var sheet.
-*/
-static gboolean
-var_sheet_cell_entry_leave (GtkSheet * sheet, gint row, gint column,
- gpointer data)
-{
- gtk_sheet_change_entry (sheet, GTK_TYPE_ENTRY);
- return TRUE;
-}
-
-
-/*
- Callback whenever the pointer enters a cell on the var sheet.
+ Callback whenever the active cell changes on the var sheet.
*/
-static gboolean
-var_sheet_cell_entry_enter (PsppireVarSheet *vs, gint row, gint column,
- gpointer data)
+static void
+var_sheet_change_active_cell (PsppireVarSheet *vs,
+ gint row, gint column,
+ gint oldrow, gint oldcolumn,
+ gpointer data)
{
GtkSheetCellAttr attributes;
- PsppireVarStore *var_store ;
+ PsppireVarStore *var_store;
PsppireVarSheetClass *vs_class =
PSPPIRE_VAR_SHEET_CLASS(G_OBJECT_GET_CLASS (vs));
struct variable *var ;
GtkSheet *sheet = GTK_SHEET (vs);
- g_return_val_if_fail (sheet != NULL, FALSE);
+ g_return_if_fail (sheet != NULL);
var_store = PSPPIRE_VAR_STORE (gtk_sheet_get_model (sheet));
g_assert (var_store);
- if ( row >= psppire_var_store_get_var_cnt (var_store))
- return TRUE;
+ g_return_if_fail (oldcolumn == PSPPIRE_VAR_STORE_COL_NAME ||
+ row < psppire_var_store_get_var_cnt (var_store));
gtk_sheet_get_attributes (sheet, row, column, &attributes);
-
var = psppire_var_store_get_var (var_store, row);
switch (column)
{
case PSPPIRE_VAR_STORE_COL_ALIGN:
{
+ GtkEntry *entry;
static GtkListStore *list_store = NULL;
GtkComboBoxEntry *cbe;
gtk_sheet_change_entry (sheet, GTK_TYPE_COMBO_BOX_ENTRY);
- cbe =
- GTK_COMBO_BOX_ENTRY (gtk_sheet_get_entry (sheet)->parent);
-
+ entry = gtk_sheet_get_entry (sheet);
+ cbe = GTK_COMBO_BOX_ENTRY (GTK_WIDGET (entry)->parent);
if ( ! list_store) list_store = create_label_list (alignments);
case PSPPIRE_VAR_STORE_COL_MEASURE:
{
+ GtkEntry *entry;
GtkComboBoxEntry *cbe;
gtk_sheet_change_entry (sheet, GTK_TYPE_COMBO_BOX_ENTRY);
- cbe =
- GTK_COMBO_BOX_ENTRY (gtk_sheet_get_entry (sheet)->parent);
-
-
+ entry = gtk_sheet_get_entry (sheet);
+ cbe = GTK_COMBO_BOX_ENTRY (GTK_WIDGET (entry)->parent);
gtk_combo_box_set_model (GTK_COMBO_BOX (cbe),
GTK_TREE_MODEL (vs_class->measure_list));
gtk_sheet_change_entry (sheet, GTK_TYPE_ENTRY);
break;
}
-
-
- return TRUE;
}
-
-
static void
psppire_var_sheet_init (PsppireVarSheet *vs)
{
- gint i;
- GObject *geo = g_sheet_hetero_column_new (75, PSPPIRE_VAR_STORE_n_COLS);
GladeXML *xml = XML_NEW ("data-editor.glade");
vs->val_labs_dialog = val_labs_dialog_create (xml);
vs->dispose_has_run = FALSE;
vs->may_create_vars = TRUE;
- for (i = 0 ; i < PSPPIRE_VAR_STORE_n_COLS ; ++i )
- {
- g_sheet_hetero_column_set_button_label (G_SHEET_HETERO_COLUMN (geo), i,
- gettext (column_def[i].label));
-
- g_sheet_hetero_column_set_width (G_SHEET_HETERO_COLUMN (geo), i,
- column_def[i].width);
- }
-
- g_object_set (vs, "column-geometry", geo, NULL);
-
-
g_signal_connect (vs, "activate",
- G_CALLBACK (var_sheet_cell_entry_enter),
- NULL);
-
- g_signal_connect (vs, "deactivate",
- G_CALLBACK (var_sheet_cell_entry_leave),
+ G_CALLBACK (var_sheet_change_active_cell),
NULL);
g_signal_connect (vs, "traverse",
}
+static const struct column_parameters column_def[] = {
+ { N_("Name"), 80},
+ { N_("Type"), 100},
+ { N_("Width"), 57},
+ { N_("Decimals"),91},
+ { N_("Label"), 95},
+ { N_("Values"), 103},
+ { N_("Missing"), 95},
+ { N_("Columns"), 80},
+ { N_("Align"), 69},
+ { N_("Measure"), 99},
+};
+
GtkWidget*
psppire_var_sheet_new (void)
{
- return GTK_WIDGET (g_object_new (psppire_var_sheet_get_type (), NULL));
+ gint i;
+ PsppireAxisImpl *ha = psppire_axis_impl_new ();
+ PsppireAxisImpl *va = psppire_axis_impl_new ();
+
+ GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL);
+
+ for (i = 0 ; i < 10 ; ++i)
+ psppire_axis_impl_append (ha, column_def[i].width);
+
+ g_object_set (va,
+ "default-size", 25,
+ NULL);
+
+ g_object_set (ha, "minimum-extent", 0,
+ NULL);
+
+ g_object_set (w,
+ "horizontal-axis", ha,
+ "vertical-axis", va,
+ NULL);
+
+ return w;
}
#include <gtksheet/gsheetmodel.h>
#include "psppire-var-store.h"
-#include <gtksheet/gsheet-row-iface.h>
#include "helper.h"
#include <data/dictionary.h>
enum
{
- PSPPIRE_VAR_STORE_TRAILING_ROWS = 1,
+ PROP_0,
PSPPIRE_VAR_STORE_FORMAT_TYPE
};
static gchar *text_for_column (const struct variable *pv, gint c, GError **err);
-static void psppire_var_store_sheet_row_init (GSheetRowIface *iface);
-
-
-
static GObjectClass *parent_class = NULL;
GType
NULL
};
- static const GInterfaceInfo sheet_row_info =
- {
- (GInterfaceInitFunc) psppire_var_store_sheet_row_init,
- NULL,
- NULL
- };
-
var_store_type = g_type_register_static (G_TYPE_OBJECT, "PsppireVarStore", &var_store_info, 0);
g_type_add_interface_static (var_store_type,
G_TYPE_SHEET_MODEL,
&sheet_model_info);
-
- g_type_add_interface_static (var_store_type,
- G_TYPE_SHEET_ROW,
- &sheet_row_info);
-
-
}
return var_store_type;
switch (property_id)
{
- case PSPPIRE_VAR_STORE_TRAILING_ROWS:
- self->trailing_rows = g_value_get_int (value);
- break;
-
case PSPPIRE_VAR_STORE_FORMAT_TYPE:
self->format_type = g_value_get_enum (value);
break;
switch (property_id)
{
- case PSPPIRE_VAR_STORE_TRAILING_ROWS:
- g_value_set_int (value, self->trailing_rows);
- break;
-
case PSPPIRE_VAR_STORE_FORMAT_TYPE:
g_value_set_enum (value, self->format_type);
break;
object_class->set_property = psppire_var_store_set_property;
object_class->get_property = psppire_var_store_get_property;
- /* The minimum value for trailing-rows is 1 to prevent the
- var-store from ever having 0 rows, which breaks invariants
- in gtksheet. */
- pspec = g_param_spec_int ("trailing-rows",
- "Trailing rows",
- "Number of rows displayed after last variable",
- 1 /* minimum value */,
- 100 /* maximum value */,
- 40 /* default value */,
- G_PARAM_READWRITE);
- g_object_class_install_property (object_class,
- PSPPIRE_VAR_STORE_TRAILING_ROWS,
- pspec);
-
pspec = g_param_spec_enum ("format-type",
"Variable format type",
("Whether variables have input or output "
G_TYPE_PSPPIRE_VAR_STORE_FORMAT_TYPE,
PSPPIRE_VAR_STORE_OUTPUT_FORMATS,
G_PARAM_READWRITE);
+
g_object_class_install_property (object_class,
PSPPIRE_VAR_STORE_FORMAT_TYPE,
pspec);
}
+#define DISABLED_COLOR "gray"
+
static void
psppire_var_store_init (PsppireVarStore *var_store)
{
- GdkColormap *colormap = gdk_colormap_get_system ();
-
- g_assert (gdk_color_parse ("gray", &var_store->disabled));
-
- gdk_colormap_alloc_color (colormap, &var_store->disabled, FALSE, TRUE);
+ if ( ! gdk_color_parse (DISABLED_COLOR, &var_store->disabled))
+ g_critical ("Could not parse color \"%s\"", DISABLED_COLOR);
var_store->dict = 0;
- var_store->trailing_rows = 40;
var_store->format_type = PSPPIRE_VAR_STORE_OUTPUT_FORMATS;
}
}
-static const GdkColor *
+static GdkColor *
psppire_var_store_get_foreground (const GSheetModel *model, glong row, glong column)
{
PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
}
-const PangoFontDescription *
-psppire_var_store_get_font_desc (const GSheetModel *model,
- glong row, glong column)
-{
- PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
-
- return store->font_desc;
-}
-
-
-
+static gchar *get_column_title (const GSheetModel *model, gint col);
+static gchar *get_row_title (const GSheetModel *model, gint row);
+static gboolean get_row_sensitivity (const GSheetModel *model, gint row);
static void
psppire_var_store_sheet_model_init (GSheetModelIface *iface)
iface->set_string = psppire_var_store_set_string;
iface->clear_datum = psppire_var_store_clear;
iface->is_editable = psppire_var_store_is_editable;
- iface->is_visible = NULL;
iface->get_foreground = psppire_var_store_get_foreground;
iface->get_background = NULL;
- iface->get_font_desc = psppire_var_store_get_font_desc;
- iface->get_cell_border = NULL;
-}
+ iface->get_justification = NULL;
+ iface->get_column_title = get_column_title;
+ iface->get_row_title = get_row_title;
+ iface->get_row_sensitivity = get_row_sensitivity;
+}
/**
* psppire_var_store_new:
}
-void
-psppire_var_store_set_font (PsppireVarStore *store, const PangoFontDescription *fd)
-{
- g_return_if_fail (store);
- g_return_if_fail (PSPPIRE_IS_VAR_STORE (store));
-
- store->font_desc = fd;
-
- g_sheet_model_range_changed (G_SHEET_MODEL (store), -1, -1, -1, -1);
-}
-
-
static glong
psppire_var_store_get_row_count (const GSheetModel * model)
{
return PSPPIRE_VAR_STORE_n_COLS ;
}
+\f
/* Row related funcs */
-static glong
-geometry_get_row_count (const GSheetRow *geom)
-{
- gint rows = 0;
- PsppireVarStore *vs = PSPPIRE_VAR_STORE (geom);
-
- if (vs->dict)
- rows = psppire_dict_get_var_cnt (vs->dict);
-
- return rows + vs->trailing_rows;
-}
-
-
-static gint
-geometry_get_height (const GSheetRow *geom, glong row)
-{
- return 25;
-}
-
static gboolean
-geometry_is_sensitive (const GSheetRow *geom, glong row)
+get_row_sensitivity (const GSheetModel *model, gint row)
{
- PsppireVarStore *vs = PSPPIRE_VAR_STORE (geom);
+ PsppireVarStore *vs = PSPPIRE_VAR_STORE (model);
if ( ! vs->dict)
return FALSE;
return row < psppire_dict_get_var_cnt (vs->dict);
}
-static
-gboolean always_true ()
-{
- return TRUE;
-}
-
static gchar *
-geometry_get_button_label (const GSheetRow *geom, glong unit)
+get_row_title (const GSheetModel *model, gint unit)
{
- gchar *label = g_strdup_printf (_("%ld"), unit + 1);
-
- return label;
+ return g_strdup_printf (_("%d"), unit + 1);
}
-static void
-psppire_var_store_sheet_row_init (GSheetRowIface *iface)
-{
- iface->get_row_count = geometry_get_row_count;
- iface->get_height = geometry_get_height;
- iface->set_height = 0;
- iface->get_visibility = always_true;
- iface->get_sensitivity = geometry_is_sensitive;
- iface->get_button_label = geometry_get_button_label;
-}
+\f
+static const gchar *column_titles[] = {
+ N_("Name"),
+ N_("Type"),
+ N_("Width"),
+ N_("Decimals"),
+ N_("Label"),
+ N_("Values"),
+ N_("Missing"),
+ N_("Columns"),
+ N_("Align"),
+ N_("Measure"),
+};
+static gchar *
+get_column_title (const GSheetModel *model, gint col)
+{
+ if ( col >= 10)
+ return NULL;
+ return g_strdup (gettext (column_titles[col]));
+}
#ifndef __PSPPIRE_VAR_STORE_H__
#define __PSPPIRE_VAR_STORE_H__
-#include <gtksheet/gsheetmodel.h>
#include "psppire-dict.h"
#include <gdk/gdk.h>
/*< private >*/
PsppireDict *dict;
GdkColor disabled;
- const PangoFontDescription *font_desc;
- gint trailing_rows;
PsppireVarStoreFormatType format_type;
};
static void
replace_casereader (struct casereader *s)
{
- PsppireCaseFile *pcf = psppire_case_file_new (s);
-
- psppire_data_store_set_case_file (the_data_store, pcf);
+ psppire_data_store_set_reader (the_data_store, s);
}
#define _(msgid) gettext (msgid)
hold a reference via ia->formats.dict. */
var_store = psppire_var_store_new (psppire_dict);
g_object_set (var_store,
- "trailing-rows", 1,
"format-type", PSPPIRE_VAR_STORE_INPUT_FORMATS,
(void *) NULL);
var_sheet = PSPPIRE_VAR_SHEET (psppire_var_sheet_new ());
g_object_set (var_sheet,
- "row-geometry", var_store,
"model", var_store,
"may-create-vars", FALSE,
(void *) NULL);
/* A block expected to be found in a tower. */
struct expected_block
{
- int height; /* Expected height of bottom of block. */
+ int size; /* Expected thickness of block. */
int x; /* Expected value for `x' member. */
};
struct tower_node *node;
size_t i;
+ check (tower_count (t) == block_cnt);
check (tower_is_empty (t) == (block_cnt == 0));
total_height = 0;
{
unsigned long int level;
for (level = total_height;
- level < total_height + blocks[i].height;
+ level < total_height + blocks[i].size;
level++)
{
struct tower_node *found;
check (found != NULL);
check (tower_node_to_block (found)->x == blocks[i].x);
check (block_start == total_height);
+ check (tower_node_get_level (found) == total_height);
+ check (tower_node_get_index (found) == i);
+ check (tower_get (t, i) == found);
}
- total_height += blocks[i].height;
+ total_height += blocks[i].size;
}
check (tower_height (t) == total_height);
node != NULL;
node = tower_next (t, node), i++)
{
- check (tower_node_get_height (node) == blocks[i].height);
+ check (tower_node_get_size (node) == blocks[i].size);
check (tower_node_to_block (node)->x == blocks[i].x);
}
check (i == block_cnt);
node != NULL;
node = tower_prev (t, node), i--)
{
- check (tower_node_get_height (node) == blocks[i].height);
+ check (tower_node_get_size (node) == blocks[i].size);
check (tower_node_to_block (node)->x == blocks[i].x);
}
check (i == SIZE_MAX);
{
unsigned int composition_cnt;
struct expected_block *expected;
- int *heights;
+ int *sizes;
int block_cnt;
int *order;
struct block *blocks;
expected = xnmalloc (cnt, sizeof *expected);
- heights = xnmalloc (cnt, sizeof *heights);
+ sizes = xnmalloc (cnt, sizeof *sizes);
order = xnmalloc (cnt, sizeof *order);
blocks = xnmalloc (cnt, sizeof *blocks);
block_cnt = 0;
composition_cnt = 0;
- while (next_composition (cnt, &block_cnt, heights))
+ while (next_composition (cnt, &block_cnt, sizes))
{
int i, j;
unsigned int permutation_cnt;
struct tower t;
/* Inserts the block_cnt blocks with the given
- heights[] into T in the order given by order[]. */
+ sizes[] into T in the order given by order[]. */
tower_init (&t);
for (i = 0; i < block_cnt; i++)
{
&& (under == NULL || under->x > order[j]))
under = &blocks[order[j]];
- tower_insert (&t, heights[idx], &blocks[idx].node,
+ tower_insert (&t, sizes[idx], &blocks[idx].node,
under != NULL ? &under->node : NULL);
}
/* Check that the result is what we expect. */
for (i = 0; i < block_cnt; i++)
{
- expected[i].height = heights[i];
+ expected[i].size = sizes[i];
expected[i].x = i;
}
check_tower (&t, expected, block_cnt);
check (composition_cnt == 1 << (cnt - 1));
free (expected);
- free (heights);
+ free (sizes);
free (order);
free (blocks);
}
}
/* Tests deleting blocks from towers that initially contain all
- possible sets of block heights into a tower in all possible
+ possible sets of block sizes into a tower in all possible
orders, up to a specified maximum tower height. */
static void
test_delete (void)
{
unsigned int composition_cnt;
struct expected_block *expected;
- int *heights;
+ int *sizes;
int block_cnt;
int *order;
struct block *blocks;
expected = xnmalloc (cnt, sizeof *expected);
- heights = xnmalloc (cnt, sizeof *heights);
+ sizes = xnmalloc (cnt, sizeof *sizes);
order = xnmalloc (cnt, sizeof *order);
blocks = xnmalloc (cnt, sizeof *blocks);
block_cnt = 0;
composition_cnt = 0;
- while (next_composition (cnt, &block_cnt, heights))
+ while (next_composition (cnt, &block_cnt, sizes))
{
int i;
unsigned int permutation_cnt;
for (i = 0; i < block_cnt; i++)
{
blocks[i].x = i;
- tower_insert (&t, heights[i], &blocks[i].node, NULL);
+ tower_insert (&t, sizes[i], &blocks[i].node, NULL);
expected[i].x = i;
- expected[i].height = heights[i];
+ expected[i].size = sizes[i];
}
check_tower (&t, expected, block_cnt);
check (composition_cnt == 1 << (cnt - 1));
free (expected);
- free (heights);
+ free (sizes);
free (order);
free (blocks);
}
}
-/* Tests towers containing all possible block heights, resizing
- the blocks to all possible heights that conserve the total
+/* Tests towers containing all possible block sizes, resizing
+ the blocks to all possible sizes that conserve the total
tower height, up to a maximum total tower height. */
static void
test_resize (void)
{
unsigned int composition_cnt;
struct expected_block *expected;
- int *heights, *new_heights;
+ int *sizes, *new_sizes;
int block_cnt;
int *order;
struct block *blocks;
expected = xnmalloc (cnt, sizeof *expected);
- heights = xnmalloc (cnt, sizeof *heights);
- new_heights = xnmalloc (cnt, sizeof *new_heights);
+ sizes = xnmalloc (cnt, sizeof *sizes);
+ new_sizes = xnmalloc (cnt, sizeof *new_sizes);
order = xnmalloc (cnt, sizeof *order);
blocks = xnmalloc (cnt, sizeof *blocks);
block_cnt = 0;
composition_cnt = 0;
- while (next_composition (cnt, &block_cnt, heights))
+ while (next_composition (cnt, &block_cnt, sizes))
{
int i;
unsigned int resizes = 0;
- for (resizes = 0, first_k_composition (cnt, block_cnt, new_heights);
+ for (resizes = 0, first_k_composition (cnt, block_cnt, new_sizes);
(resizes == 0
- || next_k_composition (cnt, block_cnt, new_heights));
+ || next_k_composition (cnt, block_cnt, new_sizes));
resizes++)
{
struct tower t;
for (i = 0; i < block_cnt; i++)
{
blocks[i].x = i;
- tower_insert (&t, heights[i], &blocks[i].node, NULL);
+ tower_insert (&t, sizes[i], &blocks[i].node, NULL);
expected[i].x = i;
- expected[i].height = heights[i];
+ expected[i].size = sizes[i];
}
check_tower (&t, expected, block_cnt);
/* Resize all the blocks. */
for (i = 0; i < block_cnt; i++)
{
- if (expected[i].height != new_heights[i] || rand () % 2)
- tower_resize (&t, &blocks[i].node, new_heights[i]);
- expected[i].height = new_heights[i];
+ if (expected[i].size != new_sizes[i] || rand () % 2)
+ tower_resize (&t, &blocks[i].node, new_sizes[i]);
+ expected[i].size = new_sizes[i];
}
check_tower (&t, expected, block_cnt);
}
check (composition_cnt == 1 << (cnt - 1));
free (expected);
- free (new_heights);
- free (heights);
+ free (new_sizes);
+ free (sizes);
free (order);
free (blocks);
}
{
unsigned int composition_cnt;
struct expected_block *expected;
- int *heights, *new_heights;
+ int *sizes, *new_sizes;
int block_cnt;
int *order;
struct block *blocks;
expected = xnmalloc (cnt, sizeof *expected);
- heights = xnmalloc (cnt, sizeof *heights);
- new_heights = xnmalloc (cnt, sizeof *new_heights);
+ sizes = xnmalloc (cnt, sizeof *sizes);
+ new_sizes = xnmalloc (cnt, sizeof *new_sizes);
order = xnmalloc (cnt, sizeof *order);
blocks = xnmalloc (cnt, sizeof *blocks);
block_cnt = 0;
composition_cnt = 0;
- while (next_composition (cnt, &block_cnt, heights))
+ while (next_composition (cnt, &block_cnt, sizes))
{
int i, j;
for (k = 0; k < block_cnt; k++)
{
blocks[k].x = k;
- tower_insert (&src, heights[k], &blocks[k].node, NULL);
+ tower_insert (&src, sizes[k], &blocks[k].node, NULL);
expected[k].x = k;
- expected[k].height = heights[k];
+ expected[k].size = sizes[k];
}
check_tower (&src, expected, block_cnt);
check (composition_cnt == 1 << (cnt - 1));
free (expected);
- free (new_heights);
- free (heights);
+ free (new_sizes);
+ free (sizes);
free (order);
free (blocks);
}
{
unsigned int composition_cnt;
struct expected_block *expected;
- int *heights, *new_heights;
+ int *sizes, *new_sizes;
int block_cnt;
int *order;
struct block *blocks;
expected = xnmalloc (cnt, sizeof *expected);
- heights = xnmalloc (cnt, sizeof *heights);
- new_heights = xnmalloc (cnt, sizeof *new_heights);
+ sizes = xnmalloc (cnt, sizeof *sizes);
+ new_sizes = xnmalloc (cnt, sizeof *new_sizes);
order = xnmalloc (cnt, sizeof *order);
blocks = xnmalloc (cnt, sizeof *blocks);
block_cnt = 0;
composition_cnt = 0;
- while (next_composition (cnt, &block_cnt, heights))
+ while (next_composition (cnt, &block_cnt, sizes))
{
int i, j;
{
blocks[k].x = k;
tower_insert (k >= i && k < j ? &src : &dst,
- heights[k], &blocks[k].node, NULL);
+ sizes[k], &blocks[k].node, NULL);
expected[k].x = k;
- expected[k].height = heights[k];
+ expected[k].size = sizes[k];
}
/* Splice SRC into DST. */
check (composition_cnt == 1 << (cnt - 1));
free (expected);
- free (new_heights);
- free (heights);
+ free (new_sizes);
+ free (sizes);
free (order);
free (blocks);
}