From: Ben Pfaff Date: Tue, 20 Mar 2012 04:41:35 +0000 (-0700) Subject: gtk-contrib: Remove GtkSheet-derived PsppireSheet. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83d072f018123f29af27a730a9ac2653ca67eea8;p=pspp gtk-contrib: Remove GtkSheet-derived PsppireSheet. This code is no longer used. --- diff --git a/lib/gtk-contrib/README b/lib/gtk-contrib/README index e6e23d944a..c3ffaf2c66 100644 --- a/lib/gtk-contrib/README +++ b/lib/gtk-contrib/README @@ -3,8 +3,3 @@ This is not part of the GNU PSPP program, but is used with GNU PSPP. This directory contains a version of the GtkXPaned widget. It includes minor modifications. GtkXPaned is licensed under the GNU Lesser General Public License. See COPYING.LESSER. - - -This directory also contains the PsppireSheet widget which is a very -heavily modified version of GtkSheet widget. This modified version if -licensed under the GNU General Public License version 3 or later. diff --git a/lib/gtk-contrib/automake.mk b/lib/gtk-contrib/automake.mk index e694d714cd..e28c4933cd 100644 --- a/lib/gtk-contrib/automake.mk +++ b/lib/gtk-contrib/automake.mk @@ -1,14 +1,10 @@ ## Process this file with automake to produce Makefile.in -*- makefile -*- -noinst_LIBRARIES += lib/gtk-contrib/libgtksheet.a +noinst_LIBRARIES += lib/gtk-contrib/libxpaned.a -lib_gtk_contrib_libgtksheet_a_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/ui/gui/include -lib_gtk_contrib_libgtksheet_a_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1 +lib_gtk_contrib_libxpaned_a_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1 -lib_gtk_contrib_libgtksheet_a_SOURCES = \ - lib/gtk-contrib/gtkextra-sheet.h \ - lib/gtk-contrib/psppire-sheet.c \ - lib/gtk-contrib/psppire-sheet.h \ +lib_gtk_contrib_libxpaned_a_SOURCES = \ lib/gtk-contrib/gtkxpaned.c \ lib/gtk-contrib/gtkxpaned.h diff --git a/lib/gtk-contrib/gtkextra-sheet.h b/lib/gtk-contrib/gtkextra-sheet.h deleted file mode 100644 index 6cad27fc40..0000000000 --- a/lib/gtk-contrib/gtkextra-sheet.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This version of GtkSheet has been heavily modified, for the specific - * requirements of PSPPIRE. - * - * GtkSheet widget for Gtk+. - * Copyright (C) 1999-2001 Adrian E. Feiguin - * - * Based on GtkClist widget by Jay Painter, but major changes. - * Memory allocation routines inspired on SC (Spreadsheet Calculator) - * - * 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 PSPPIRE_EXTRA_SHEET_H__ -#define PSPPIRE_EXTRA_SHEET_H__ - - -struct _PsppireSheet ; - -typedef struct _PsppireSheet PsppireSheet; - - -struct _PsppireSheetButton -{ - GtkStateType state; - gchar *label; - - gboolean label_visible; - - GtkJustification justification; - gboolean overstruck; -}; - -struct _PsppireSheetCell -{ - gint row; - gint col; -}; - -typedef struct _PsppireSheetButton PsppireSheetButton; -typedef struct _PsppireSheetCell PsppireSheetCell; - -PsppireSheetButton * psppire_sheet_button_new (void); - -void psppire_sheet_button_free (PsppireSheetButton *button); - - -#endif /* PSPPIRE_EXTRA_SHEET_H__ */ - - diff --git a/lib/gtk-contrib/psppire-sheet.c b/lib/gtk-contrib/psppire-sheet.c deleted file mode 100644 index ecadf742cb..0000000000 --- a/lib/gtk-contrib/psppire-sheet.c +++ /dev/null @@ -1,4882 +0,0 @@ -/* - Copyright (C) 2006, 2008, 2009, 2011 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 . - - - This file is derived from the gtksheet.c and extensively modified for the - requirements of PSPPIRE. The changes are copyright by the - Free Software Foundation. The copyright notice for the original work is - below. -*/ - -/* GtkSheet widget for Gtk+. - * Copyright (C) 1999-2001 Adrian E. Feiguin - * - * Based on GtkClist widget by Jay Painter, but major changes. - * Memory allocation routines inspired on SC (Spreadsheet Calculator) - * - * 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 - */ - -/** - * SECTION:psppiresheet - * @short_description: spreadsheet widget for gtk2 - * - * PsppireSheet 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. - * - */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "psppire-sheet.h" -#include -#include -#include -#include - -/* sheet flags */ -enum - { - PSPPIRE_SHEET_IN_XDRAG = 1 << 1, - PSPPIRE_SHEET_IN_YDRAG = 1 << 2, - PSPPIRE_SHEET_IN_DRAG = 1 << 3, - - /* This flag is set when the user is actually in the process - of making a selection - ie while the mouse button is - depressed. - */ - PSPPIRE_SHEET_IN_SELECTION = 1 << 4 - }; - -#define PSPPIRE_SHEET_FLAGS(sheet) (PSPPIRE_SHEET (sheet)->flags) -#define PSPPIRE_SHEET_SET_FLAGS(sheet,flag) (PSPPIRE_SHEET_FLAGS (sheet) |= (flag)) -#define PSPPIRE_SHEET_UNSET_FLAGS(sheet,flag) (PSPPIRE_SHEET_FLAGS (sheet) &= ~ (flag)) - -#define PSPPIRE_SHEET_IN_XDRAG(sheet) (PSPPIRE_SHEET_FLAGS (sheet) & PSPPIRE_SHEET_IN_XDRAG) -#define PSPPIRE_SHEET_IN_YDRAG(sheet) (PSPPIRE_SHEET_FLAGS (sheet) & PSPPIRE_SHEET_IN_YDRAG) -#define PSPPIRE_SHEET_IN_DRAG(sheet) (PSPPIRE_SHEET_FLAGS (sheet) & PSPPIRE_SHEET_IN_DRAG) -#define PSPPIRE_SHEET_IN_SELECTION(sheet) (PSPPIRE_SHEET_FLAGS (sheet) & PSPPIRE_SHEET_IN_SELECTION) - -#define CELL_SPACING 1 - -#define TIMEOUT_HOVER 300 -#define COLUMN_MIN_WIDTH 10 -#define COLUMN_TITLES_HEIGHT 4 -#define DEFAULT_COLUMN_WIDTH 80 -#define DEFAULT_ROW_HEIGHT 25 - -static void set_entry_widget_font (PsppireSheet *sheet); - -static void psppire_sheet_update_primary_selection (PsppireSheet *sheet); -static void draw_column_title_buttons_range (PsppireSheet *sheet, gint first, gint n); -static void draw_row_title_buttons_range (PsppireSheet *sheet, gint first, gint n); -static void redraw_range (PsppireSheet *sheet, PsppireSheetRange *range); - - -static void set_row_height (PsppireSheet *sheet, - gint row, - gint height); - -static void destroy_hover_window (PsppireSheetHoverTitle *); -static PsppireSheetHoverTitle *create_hover_window (void); - -static inline void -dispose_string (const PsppireSheet *sheet, gchar *text) -{ - PsppireSheetModel *model = psppire_sheet_get_model (sheet); - - if ( ! model ) - return; - - if (psppire_sheet_model_free_strings (model)) - g_free (text); -} - - -/* FIXME: Why bother with these two ? */ - -/* returns the column index from a pixel location */ -static inline gint -column_from_xpixel (const PsppireSheet *sheet, gint pixel) -{ - return psppire_axis_unit_at_pixel (sheet->haxis, pixel); -} - -static inline gint -row_from_ypixel (const PsppireSheet *sheet, gint pixel) -{ - return psppire_axis_unit_at_pixel (sheet->vaxis, pixel); -} - - -/* Return the lowest row number which is wholly or partially on - the visible range of the sheet */ -static inline glong -min_visible_row (const PsppireSheet *sheet) -{ - return row_from_ypixel (sheet, sheet->vadjustment->value); -} - -static inline glong -min_fully_visible_row (const PsppireSheet *sheet) -{ - glong row = min_visible_row (sheet); - - if ( psppire_axis_start_pixel (sheet->vaxis, row) < sheet->vadjustment->value) - row++; - - return row; -} - -static inline glong -max_visible_row (const PsppireSheet *sheet) -{ - return row_from_ypixel (sheet, sheet->vadjustment->value + sheet->vadjustment->page_size); -} - - -static inline glong -max_fully_visible_row (const PsppireSheet *sheet) -{ - glong row = max_visible_row (sheet); - - if ( psppire_axis_start_pixel (sheet->vaxis, row) - + - psppire_axis_unit_size (sheet->vaxis, row) - > sheet->vadjustment->value) - row--; - - return row; -} - - -/* Returns the lowest column number which is wholly or partially - on the sheet */ -static inline glong -min_visible_column (const PsppireSheet *sheet) -{ - return column_from_xpixel (sheet, sheet->hadjustment->value); -} - -static inline glong -min_fully_visible_column (const PsppireSheet *sheet) -{ - glong col = min_visible_column (sheet); - - if ( psppire_axis_start_pixel (sheet->haxis, col) < sheet->hadjustment->value) - col++; - - return col; -} - - -/* Returns the highest column number which is wholly or partially - on the sheet */ -static inline glong -max_visible_column (const PsppireSheet *sheet) -{ - return column_from_xpixel (sheet, sheet->hadjustment->value + sheet->hadjustment->page_size); -} - -static inline glong -max_fully_visible_column (const PsppireSheet *sheet) -{ - glong col = max_visible_column (sheet); - - if ( psppire_axis_start_pixel (sheet->haxis, col) - + - psppire_axis_unit_size (sheet->haxis, col) - > sheet->hadjustment->value) - col--; - - return col; -} - - - -/* 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 gboolean -on_column_boundary (const PsppireSheet *sheet, gint x, gint *column) -{ - gint col; - gint pixel; - - x += sheet->hadjustment->value; - - if ( x < 0) - return FALSE; - - col = column_from_xpixel (sheet, x); - - pixel = x - DRAG_WIDTH / 2; - if (pixel < 0) - pixel = 0; - - if ( column_from_xpixel (sheet, pixel) < col ) - { - *column = col - 1; - return TRUE; - } - - if ( column_from_xpixel (sheet, x + DRAG_WIDTH / 2) > col ) - { - *column = col; - return TRUE; - } - - return FALSE; -} - -static gboolean -on_row_boundary (const PsppireSheet *sheet, gint y, gint *row) -{ - gint r; - gint pixel; - - y += sheet->vadjustment->value; - - if ( y < 0) - return FALSE; - - r = row_from_ypixel (sheet, y); - - pixel = y - DRAG_WIDTH / 2; - if (pixel < 0) - pixel = 0; - - if ( row_from_ypixel (sheet, pixel) < r ) - { - *row = r - 1; - return TRUE; - } - - if ( row_from_ypixel (sheet, y + DRAG_WIDTH / 2) > r ) - { - *row = r; - return TRUE; - } - - return FALSE; -} - - -static inline gboolean -POSSIBLE_DRAG (const PsppireSheet *sheet, gint x, gint y, - gint *drag_row, gint *drag_column) -{ - gint ydrag, xdrag; - - /* Can't drag if nothing is selected */ - if ( sheet->range.row0 < 0 || sheet->range.rowi < 0 || - sheet->range.col0 < 0 || sheet->range.coli < 0 ) - return FALSE; - - *drag_column = column_from_xpixel (sheet, x); - *drag_row = row_from_ypixel (sheet, y); - - 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 = 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 = 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; - return TRUE; - } - } - - 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 = 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 = 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; - return TRUE; - } - } - - return FALSE; -} - -static inline gboolean -POSSIBLE_RESIZE (const PsppireSheet *sheet, gint x, gint y, - gint *drag_row, gint *drag_column) -{ - gint xdrag, ydrag; - - /* Can't drag if nothing is selected */ - if ( sheet->range.row0 < 0 || sheet->range.rowi < 0 || - sheet->range.col0 < 0 || sheet->range.coli < 0 ) - return FALSE; - - xdrag = psppire_axis_start_pixel (sheet->haxis, sheet->range.coli)+ - psppire_axis_unit_size (sheet->haxis, sheet->range.coli); - - ydrag = psppire_axis_start_pixel (sheet->vaxis, sheet->range.rowi) + - psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi); - - if (sheet->select_status == PSPPIRE_SHEET_COLUMN_SELECTED) - ydrag = psppire_axis_start_pixel (sheet->vaxis, min_visible_row (sheet)); - - if (sheet->select_status == PSPPIRE_SHEET_ROW_SELECTED) - 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); - - 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 -rectangle_from_range (PsppireSheet *sheet, const PsppireSheetRange *range, - GdkRectangle *r) -{ - gint col0 = MIN (range->col0, range->coli); - gint coli = MAX (range->col0, range->coli); - gint row0 = MIN (range->row0, range->rowi); - gint rowi = MAX (range->row0, range->rowi); - - if ( row0 == -1 ) row0 = min_visible_row (sheet); - if ( rowi == -1 ) rowi = max_visible_row (sheet); - if ( col0 == -1 ) col0 = min_visible_column (sheet); - if ( coli == -1 ) coli = max_visible_column (sheet); - - r->x = psppire_axis_start_pixel (sheet->haxis, col0); - r->x -= round (sheet->hadjustment->value); - - r->y = psppire_axis_start_pixel (sheet->vaxis, row0); - r->y -= round (sheet->vadjustment->value); - - r->width = psppire_axis_start_pixel (sheet->haxis, coli) - - psppire_axis_start_pixel (sheet->haxis, col0) + - psppire_axis_unit_size (sheet->haxis, coli); - - r->height = psppire_axis_start_pixel (sheet->vaxis, rowi) - - psppire_axis_start_pixel (sheet->vaxis, row0) + - psppire_axis_unit_size (sheet->vaxis, rowi); - - if ( sheet->column_titles_visible) - { - r->y += sheet->column_title_area.height; - } - - if ( sheet->row_titles_visible) - { - r->x += sheet->row_title_area.width; - } -} - -static void -rectangle_from_cell (PsppireSheet *sheet, gint row, gint col, - GdkRectangle *r) -{ - PsppireSheetRange range; - g_return_if_fail (row >= 0); - g_return_if_fail (col >= 0); - - range.row0 = range.rowi = row; - range.col0 = range.coli = col; - - rectangle_from_range (sheet, &range, r); -} - - -static void psppire_sheet_class_init (PsppireSheetClass *klass); -static void psppire_sheet_init (PsppireSheet *sheet); -static void psppire_sheet_dispose (GObject *object); -static void psppire_sheet_finalize (GObject *object); -static void psppire_sheet_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void psppire_sheet_realize (GtkWidget *widget); -static void psppire_sheet_unrealize (GtkWidget *widget); -static void psppire_sheet_map (GtkWidget *widget); -static void psppire_sheet_unmap (GtkWidget *widget); -static gint psppire_sheet_expose (GtkWidget *widget, - GdkEventExpose *event); - -static void psppire_sheet_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static gboolean psppire_sheet_set_scroll_adjustments (PsppireSheet *sheet, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment); - -static gint psppire_sheet_button_press (GtkWidget *widget, - GdkEventButton *event); -static gint psppire_sheet_button_release (GtkWidget *widget, - GdkEventButton *event); -static gint psppire_sheet_motion (GtkWidget *widget, - GdkEventMotion *event); -static gboolean psppire_sheet_crossing_notify (GtkWidget *widget, - GdkEventCrossing *event); -static gint psppire_sheet_entry_key_press (GtkWidget *widget, - GdkEventKey *key); -static gboolean psppire_sheet_key_press (GtkWidget *widget, - GdkEventKey *key); -static void psppire_sheet_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void psppire_sheet_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); - -static gboolean psppire_sheet_focus_in (GtkWidget *widget, - GdkEventFocus *event); - -/* Sheet queries */ - -static gboolean psppire_sheet_range_isvisible (const PsppireSheet *sheet, - const PsppireSheetRange *range); -static gboolean psppire_sheet_cell_isvisible (PsppireSheet *sheet, - gint row, gint column); -/* Drawing Routines */ - -/* draw cell */ -static void psppire_sheet_cell_draw (PsppireSheet *sheet, gint row, gint column); - - -/* draw visible part of range. */ -static void draw_sheet_region (PsppireSheet *sheet, GdkRegion *region); - - -/* Selection */ -static void psppire_sheet_draw_border (PsppireSheet *sheet, - PsppireSheetRange range); - -/* Active Cell handling */ - -static void psppire_sheet_hide_entry_widget (PsppireSheet *sheet); -static void change_active_cell (PsppireSheet *sheet, gint row, gint col); -static gboolean psppire_sheet_draw_active_cell (PsppireSheet *sheet); -static void psppire_sheet_show_entry_widget (PsppireSheet *sheet); -static gboolean psppire_sheet_click_cell (PsppireSheet *sheet, - gint row, - gint column); - - -/* Scrollbars */ - -static void adjust_scrollbars (PsppireSheet *sheet); -static void vadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data); -static void hadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data); - - -static void draw_xor_vline (PsppireSheet *sheet); -static void draw_xor_hline (PsppireSheet *sheet); -static void draw_xor_rectangle (PsppireSheet *sheet, - PsppireSheetRange range); - -/* Sheet Button */ - -static void create_global_button (PsppireSheet *sheet); -static void global_button_clicked (GtkWidget *widget, - gpointer data); -/* Sheet Entry */ - -static void create_sheet_entry (PsppireSheet *sheet); -static void psppire_sheet_size_allocate_entry (PsppireSheet *sheet); - -/* Sheet button gadgets */ - -static void draw_column_title_buttons (PsppireSheet *sheet); -static void draw_row_title_buttons (PsppireSheet *sheet); - - -static void size_allocate_global_button (PsppireSheet *sheet); - -static void psppire_sheet_real_cell_clear (PsppireSheet *sheet, - gint row, - gint column); - - -/* Signals */ -enum - { - SELECT_ROW, - SELECT_COLUMN, - DOUBLE_CLICK_ROW, - DOUBLE_CLICK_COLUMN, - BUTTON_EVENT_ROW, - BUTTON_EVENT_COLUMN, - SELECT_RANGE, - RESIZE_RANGE, - MOVE_RANGE, - TRAVERSE, - ACTIVATE, - LAST_SIGNAL - }; - -static GtkContainerClass *parent_class = NULL; -static guint sheet_signals[LAST_SIGNAL] = { 0 }; - - -GType -psppire_sheet_get_type () -{ - static GType sheet_type = 0; - - if (!sheet_type) - { - static const GTypeInfo sheet_info = - { - sizeof (PsppireSheetClass), - NULL, - NULL, - (GClassInitFunc) psppire_sheet_class_init, - NULL, - NULL, - sizeof (PsppireSheet), - 0, - (GInstanceInitFunc) psppire_sheet_init, - NULL, - }; - - sheet_type = - g_type_register_static (GTK_TYPE_BIN, "PsppireSheet", - &sheet_info, 0); - } - return sheet_type; -} - - - -static PsppireSheetRange* -psppire_sheet_range_copy (const PsppireSheetRange *range) -{ - PsppireSheetRange *new_range; - - g_return_val_if_fail (range != NULL, NULL); - - new_range = g_new (PsppireSheetRange, 1); - - *new_range = *range; - - return new_range; -} - -static void -psppire_sheet_range_free (PsppireSheetRange *range) -{ - g_return_if_fail (range != NULL); - - g_free (range); -} - -GType -psppire_sheet_range_get_type (void) -{ - static GType sheet_range_type = 0; - - if (!sheet_range_type) - { - sheet_range_type = - g_boxed_type_register_static ("PsppireSheetRange", - (GBoxedCopyFunc) psppire_sheet_range_copy, - (GBoxedFreeFunc) psppire_sheet_range_free); - } - - return sheet_range_type; -} - -static PsppireSheetCell* -psppire_sheet_cell_copy (const PsppireSheetCell *cell) -{ - PsppireSheetCell *new_cell; - - g_return_val_if_fail (cell != NULL, NULL); - - new_cell = g_new (PsppireSheetCell, 1); - - *new_cell = *cell; - - return new_cell; -} - -static void -psppire_sheet_cell_free (PsppireSheetCell *cell) -{ - g_return_if_fail (cell != NULL); - - g_free (cell); -} - -GType -psppire_sheet_cell_get_type (void) -{ - static GType sheet_cell_type = 0; - - if (!sheet_cell_type) - { - sheet_cell_type = - g_boxed_type_register_static ("PsppireSheetCell", - (GBoxedCopyFunc) psppire_sheet_cell_copy, - (GBoxedFreeFunc) psppire_sheet_cell_free); - } - - return sheet_cell_type; -} - - -/* Properties */ -enum - { - PROP_0, - PROP_VAXIS, - PROP_HAXIS, - PROP_CELL_PADDING, - PROP_MODEL - }; - -static void -resize_column (PsppireSheet *sheet, gint unit, glong size) -{ - PsppireSheetRange range; - range.col0 = unit; - range.coli = max_visible_column (sheet); - range.row0 = min_visible_row (sheet); - range.rowi = max_visible_row (sheet); - - redraw_range (sheet, &range); - - draw_column_title_buttons_range (sheet, range.col0, range.coli); -} - - -static void -psppire_sheet_set_horizontal_axis (PsppireSheet *sheet, PsppireAxis *a) -{ - if ( sheet->haxis ) - g_object_unref (sheet->haxis); - - sheet->haxis = a; - g_signal_connect_swapped (a, "resize-unit", G_CALLBACK (resize_column), sheet); - - if ( sheet->haxis ) - g_object_ref (sheet->haxis); -} - -static void -resize_row (PsppireSheet *sheet, gint unit, glong size) -{ - PsppireSheetRange range; - range.col0 = min_visible_column (sheet); - range.coli = max_visible_column (sheet); - range.row0 = unit; - range.rowi = max_visible_row (sheet); - - redraw_range (sheet, &range); - - draw_row_title_buttons_range (sheet, range.row0, range.rowi); -} - -static void -psppire_sheet_set_vertical_axis (PsppireSheet *sheet, PsppireAxis *a) -{ - if ( sheet->vaxis ) - g_object_unref (sheet->vaxis); - - sheet->vaxis = a; - - g_signal_connect_swapped (a, "resize-unit", G_CALLBACK (resize_row), sheet); - - if ( sheet->vaxis ) - g_object_ref (sheet->vaxis); -} - -static const GtkBorder default_cell_padding = {3, 3, 3, 3}; - -static void -psppire_sheet_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) - -{ - PsppireSheet *sheet = PSPPIRE_SHEET (object); - - switch (prop_id) - { - case PROP_CELL_PADDING: - if ( sheet->cell_padding) - g_boxed_free (GTK_TYPE_BORDER, sheet->cell_padding); - - sheet->cell_padding = g_value_dup_boxed (value); - - if (NULL == sheet->cell_padding) - sheet->cell_padding = g_boxed_copy (GTK_TYPE_BORDER, - &default_cell_padding); - - if (sheet->vaxis) - g_object_set (sheet->vaxis, "padding", - sheet->cell_padding->top + sheet->cell_padding->bottom, - NULL); - - if (sheet->haxis) - g_object_set (sheet->haxis, "padding", - sheet->cell_padding->left + sheet->cell_padding->right, - NULL); - break; - case PROP_VAXIS: - psppire_sheet_set_vertical_axis (sheet, g_value_get_pointer (value)); - g_object_set (sheet->vaxis, "padding", - sheet->cell_padding->top + sheet->cell_padding->bottom, - NULL); - break; - case PROP_HAXIS: - psppire_sheet_set_horizontal_axis (sheet, g_value_get_pointer (value)); - g_object_set (sheet->haxis, "padding", - sheet->cell_padding->left + sheet->cell_padding->right, - NULL); - break; - case PROP_MODEL: - psppire_sheet_set_model (sheet, g_value_get_pointer (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - }; -} - -static void -psppire_sheet_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (object); - - switch (prop_id) - { - case PROP_CELL_PADDING: - g_value_set_boxed (value, sheet->cell_padding); - break; - case PROP_VAXIS: - g_value_set_pointer (value, sheet->vaxis); - break; - case PROP_HAXIS: - g_value_set_pointer (value, sheet->haxis); - break; - case PROP_MODEL: - g_value_set_pointer (value, sheet->model); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - }; -} - - -static void -psppire_sheet_class_init (PsppireSheetClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - GParamSpec *haxis_spec ; - GParamSpec *vaxis_spec ; - GParamSpec *model_spec ; - GParamSpec *cell_padding_spec ; - - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /** - * PsppireSheet::select-row - * @sheet: the sheet widget that emitted the signal - * @row: the newly selected row index, or -1 if no row is selected. - * - * A row has been selected. - */ - sheet_signals[SELECT_ROW] = - g_signal_new ("select-row", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, select_row), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - /** - * PsppireSheet::select - column - * @sheet: the sheet widget that emitted the signal - * @column: the newly selected column index, or -1 if no column is selected. - * - * A column has been selected. - */ - sheet_signals[SELECT_COLUMN] = - g_signal_new ("select-column", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, select_column), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - /** - * PsppireSheet::double-click-row - * @sheet: the sheet widget that emitted the signal - * @row: the row that was double clicked. - * - * A row's title button has been double clicked - */ - sheet_signals[DOUBLE_CLICK_ROW] = - g_signal_new ("double-click-row", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - /** - * PsppireSheet::double-click-column - * @sheet: the sheet widget that emitted the signal - * @column: the column that was double clicked. - * - * A column's title button has been double clicked - */ - sheet_signals[DOUBLE_CLICK_COLUMN] = - g_signal_new ("double-click-column", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - /** - * PsppireSheet::button-event-column - * @sheet: the sheet widget that emitted the signal - * @column: the column on which the event occured. - * - * A button event occured on a column title button - */ - sheet_signals[BUTTON_EVENT_COLUMN] = - g_signal_new ("button-event-column", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - psppire_marshal_VOID__INT_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_INT, - G_TYPE_POINTER - ); - - - /** - * PsppireSheet::button-event-row - * @sheet: the sheet widget that emitted the signal - * @column: the column on which the event occured. - * - * A button event occured on a row title button - */ - sheet_signals[BUTTON_EVENT_ROW] = - g_signal_new ("button-event-row", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - psppire_marshal_VOID__INT_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_INT, - G_TYPE_POINTER - ); - - - sheet_signals[SELECT_RANGE] = - g_signal_new ("select-range", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, select_range), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - PSPPIRE_TYPE_SHEET_RANGE); - - - sheet_signals[RESIZE_RANGE] = - g_signal_new ("resize-range", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, resize_range), - NULL, NULL, - psppire_marshal_VOID__BOXED_BOXED, - G_TYPE_NONE, - 2, - PSPPIRE_TYPE_SHEET_RANGE, PSPPIRE_TYPE_SHEET_RANGE - ); - - sheet_signals[MOVE_RANGE] = - g_signal_new ("move-range", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, move_range), - NULL, NULL, - psppire_marshal_VOID__BOXED_BOXED, - G_TYPE_NONE, - 2, - PSPPIRE_TYPE_SHEET_RANGE, PSPPIRE_TYPE_SHEET_RANGE - ); - - sheet_signals[TRAVERSE] = - g_signal_new ("traverse", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, traverse), - NULL, NULL, - psppire_marshal_BOOLEAN__BOXED_POINTER, - G_TYPE_BOOLEAN, 2, - PSPPIRE_TYPE_SHEET_CELL, - G_TYPE_POINTER); - - - sheet_signals[ACTIVATE] = - g_signal_new ("activate", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, activate), - NULL, NULL, - psppire_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, G_TYPE_INT, - G_TYPE_INT, G_TYPE_INT); - - widget_class->set_scroll_adjustments_signal = - g_signal_new ("set-scroll-adjustments", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (PsppireSheetClass, set_scroll_adjustments), - NULL, NULL, - psppire_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); - - - container_class->add = NULL; - container_class->remove = NULL; - container_class->forall = psppire_sheet_forall; - container_class->set_focus_child = NULL; - - object_class->dispose = psppire_sheet_dispose; - object_class->finalize = psppire_sheet_finalize; - - cell_padding_spec = - g_param_spec_boxed ("cell-padding", - "Cell Padding", - "The space between a cell's contents and its border", - GTK_TYPE_BORDER, - G_PARAM_CONSTRUCT | G_PARAM_READABLE | G_PARAM_WRITABLE); - - 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 ); - - 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 = - g_param_spec_pointer ("model", - "Model", - "A pointer to the data model", - G_PARAM_READABLE | G_PARAM_WRITABLE ); - - - object_class->set_property = psppire_sheet_set_property; - object_class->get_property = psppire_sheet_get_property; - - g_object_class_install_property (object_class, - PROP_VAXIS, - vaxis_spec); - - g_object_class_install_property (object_class, - PROP_HAXIS, - haxis_spec); - - g_object_class_install_property (object_class, - PROP_CELL_PADDING, - cell_padding_spec); - - g_object_class_install_property (object_class, - PROP_MODEL, - model_spec); - - - widget_class->realize = psppire_sheet_realize; - widget_class->unrealize = psppire_sheet_unrealize; - widget_class->map = psppire_sheet_map; - widget_class->unmap = psppire_sheet_unmap; - widget_class->style_set = psppire_sheet_style_set; - widget_class->button_press_event = psppire_sheet_button_press; - widget_class->button_release_event = psppire_sheet_button_release; - widget_class->motion_notify_event = psppire_sheet_motion; - widget_class->enter_notify_event = psppire_sheet_crossing_notify; - widget_class->leave_notify_event = psppire_sheet_crossing_notify; - widget_class->key_press_event = psppire_sheet_key_press; - widget_class->expose_event = psppire_sheet_expose; - widget_class->size_request = psppire_sheet_size_request; - widget_class->size_allocate = psppire_sheet_size_allocate; - widget_class->focus_in_event = psppire_sheet_focus_in; - widget_class->focus_out_event = NULL; - - klass->set_scroll_adjustments = psppire_sheet_set_scroll_adjustments; - klass->select_row = NULL; - klass->select_column = NULL; - klass->select_range = NULL; - klass->resize_range = NULL; - klass->move_range = NULL; - klass->traverse = NULL; - klass->activate = NULL; - klass->changed = NULL; -} - -static void -psppire_sheet_init (PsppireSheet *sheet) -{ - sheet->model = NULL; - sheet->haxis = NULL; - sheet->vaxis = NULL; - - sheet->flags = 0; - sheet->select_status = PSPPIRE_SHEET_NORMAL; - - GTK_WIDGET_UNSET_FLAGS (sheet, GTK_NO_WINDOW); - GTK_WIDGET_SET_FLAGS (sheet, GTK_CAN_FOCUS); - - sheet->column_title_window = NULL; - 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; - - sheet->row_title_window = NULL; - sheet->row_title_area.x = 0; - sheet->row_title_area.y = 0; - sheet->row_title_area.width = DEFAULT_COLUMN_WIDTH; - sheet->row_title_area.height = 0; - - - sheet->active_cell.row = 0; - sheet->active_cell.col = 0; - - sheet->range.row0 = 0; - sheet->range.rowi = 0; - sheet->range.col0 = 0; - sheet->range.coli = 0; - - sheet->sheet_window = NULL; - sheet->entry_widget = NULL; - sheet->button = NULL; - - sheet->hadjustment = NULL; - sheet->vadjustment = NULL; - - sheet->cursor_drag = NULL; - - sheet->xor_gc = NULL; - sheet->fg_gc = NULL; - sheet->bg_gc = NULL; - sheet->x_drag = 0; - sheet->y_drag = 0; - sheet->show_grid = TRUE; - - sheet->motion_timer = 0; - - sheet->row_titles_visible = TRUE; - sheet->row_title_area.width = DEFAULT_COLUMN_WIDTH; - - sheet->column_titles_visible = TRUE; - - - /* create sheet entry */ - sheet->entry_type = GTK_TYPE_ENTRY; - create_sheet_entry (sheet); - - /* create global selection button */ - create_global_button (sheet); -} - - -/* Cause RANGE to be redrawn. If RANGE is null, then the - entire visible range will be redrawn. -*/ -static void -redraw_range (PsppireSheet *sheet, PsppireSheetRange *range) -{ - GdkRectangle rect; - - if ( ! GTK_WIDGET_REALIZED (sheet)) - return; - - if ( NULL != range ) - rectangle_from_range (sheet, range, &rect); - else - { - GdkRegion *r = gdk_drawable_get_visible_region (sheet->sheet_window); - gdk_region_get_clipbox (r, &rect); - - if ( sheet->column_titles_visible) - { - rect.y += sheet->column_title_area.height; - rect.height -= sheet->column_title_area.height; - } - - if ( sheet->row_titles_visible) - { - rect.x += sheet->row_title_area.width; - rect.width -= sheet->row_title_area.width; - } - } - - gdk_window_invalidate_rect (sheet->sheet_window, &rect, FALSE); -} - - -/* Callback which occurs whenever columns are inserted / deleted in the model */ -static void -columns_inserted_deleted_callback (PsppireSheetModel *model, gint first_column, - gint n_columns, - gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - - PsppireSheetRange range; - gint model_columns = psppire_sheet_model_get_column_count (model); - - - /* Need to update all the columns starting from the first column and onwards. - * Previous column are unchanged, so don't need to be updated. - */ - range.col0 = first_column; - range.row0 = 0; - 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) - change_active_cell (sheet, sheet->active_cell.row, model_columns - 1); - - draw_column_title_buttons_range (sheet, - first_column, max_visible_column (sheet)); - - - redraw_range (sheet, &range); -} - - - - -/* Callback which occurs whenever rows are inserted / deleted in the model */ -static void -rows_inserted_deleted_callback (PsppireSheetModel *model, gint first_row, - gint n_rows, gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - - PsppireSheetRange range; - - gint model_rows = psppire_sheet_model_get_row_count (model); - - /* Need to update all the rows starting from the first row and onwards. - * Previous rows are unchanged, so don't need to be updated. - */ - range.row0 = first_row; - range.col0 = 0; - 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) - change_active_cell (sheet, model_rows - 1, sheet->active_cell.col); - - draw_row_title_buttons_range (sheet, first_row, max_visible_row (sheet)); - - redraw_range (sheet, &range); -} - -/* - If row0 or rowi are negative, then all rows will be updated. - If col0 or coli are negative, then all columns will be updated. -*/ -static void -range_update_callback (PsppireSheetModel *m, gint row0, gint col0, - gint rowi, gint coli, gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - - PsppireSheetRange range; - - range.row0 = row0; - range.col0 = col0; - range.rowi = rowi; - range.coli = coli; - - if ( !GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - if ( ( row0 < 0 && col0 < 0 ) || ( rowi < 0 && coli < 0 ) ) - { - redraw_range (sheet, NULL); - adjust_scrollbars (sheet); - - draw_row_title_buttons_range (sheet, min_visible_row (sheet), - max_visible_row (sheet)); - - 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); - } - else if ( col0 < 0 || coli < 0 ) - { - range.col0 = min_visible_column (sheet); - range.coli = max_visible_column (sheet); - } - - redraw_range (sheet, &range); -} - - -/** - * psppire_sheet_new: - * @rows: initial number of rows - * @columns: initial number of columns - * @title: sheet title - * @model: the model to use for the sheet data - * - * Creates a new sheet widget with the given number of rows and columns. - * - * Returns: the new sheet widget - */ -GtkWidget * -psppire_sheet_new (PsppireSheetModel *model) -{ - GtkWidget *widget = g_object_new (PSPPIRE_TYPE_SHEET, - "model", model, - NULL); - return widget; -} - - -/** - * psppire_sheet_set_model - * @sheet: the sheet to set the model for - * @model: the model to use for the sheet data - * - * Sets the model for a PsppireSheet - * - */ -void -psppire_sheet_set_model (PsppireSheet *sheet, PsppireSheetModel *model) -{ - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (sheet->model ) g_object_unref (sheet->model); - - sheet->model = model; - - if ( model) - { - g_object_ref (model); - - sheet->update_handler_id = g_signal_connect (model, "range_changed", - G_CALLBACK (range_update_callback), - sheet); - - g_signal_connect (model, "rows_inserted", - G_CALLBACK (rows_inserted_deleted_callback), sheet); - - g_signal_connect (model, "rows_deleted", - G_CALLBACK (rows_inserted_deleted_callback), sheet); - - g_signal_connect (model, "columns_inserted", - G_CALLBACK (columns_inserted_deleted_callback), sheet); - - g_signal_connect (model, "columns_deleted", - G_CALLBACK (columns_inserted_deleted_callback), sheet); - } -} - - -void -psppire_sheet_change_entry (PsppireSheet *sheet, GType entry_type) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (sheet->select_status == PSPPIRE_SHEET_NORMAL) - psppire_sheet_hide_entry_widget (sheet); - - sheet->entry_type = entry_type; - - create_sheet_entry (sheet); - - if (sheet->select_status == PSPPIRE_SHEET_NORMAL) - psppire_sheet_show_entry_widget (sheet); -} - -void -psppire_sheet_show_grid (PsppireSheet *sheet, gboolean show) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (show == sheet->show_grid) return; - - sheet->show_grid = show; - - redraw_range (sheet, NULL); -} - -gboolean -psppire_sheet_grid_visible (PsppireSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), 0); - - return sheet->show_grid; -} - -guint -psppire_sheet_get_columns_count (PsppireSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), 0); - - return psppire_axis_unit_count (sheet->haxis); -} - -static void set_column_width (PsppireSheet *sheet, - gint column, - gint width); - - -void -psppire_sheet_show_column_titles (PsppireSheet *sheet) -{ - if (sheet->column_titles_visible) return; - - sheet->column_titles_visible = TRUE; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - 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); - - adjust_scrollbars (sheet); - - if (sheet->vadjustment) - g_signal_emit_by_name (sheet->vadjustment, - "value_changed"); - - size_allocate_global_button (sheet); - - if ( sheet->row_titles_visible) - gtk_widget_show (sheet->button); -} - - -void -psppire_sheet_show_row_titles (PsppireSheet *sheet) -{ - if (sheet->row_titles_visible) return; - - sheet->row_titles_visible = TRUE; - - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - gdk_window_show (sheet->row_title_window); - gdk_window_move_resize (sheet->row_title_window, - sheet->row_title_area.x, - sheet->row_title_area.y, - sheet->row_title_area.width, - sheet->row_title_area.height); - - adjust_scrollbars (sheet); - } - - if (sheet->hadjustment) - g_signal_emit_by_name (sheet->hadjustment, - "value_changed"); - - size_allocate_global_button (sheet); - - if ( sheet->column_titles_visible) - gtk_widget_show (sheet->button); -} - -void -psppire_sheet_hide_column_titles (PsppireSheet *sheet) -{ - if (!sheet->column_titles_visible) return; - - sheet->column_titles_visible = FALSE; - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - if (sheet->column_title_window) - gdk_window_hide (sheet->column_title_window); - - gtk_widget_hide (sheet->button); - - adjust_scrollbars (sheet); - } - - if (sheet->vadjustment) - g_signal_emit_by_name (sheet->vadjustment, - "value_changed"); -} - -void -psppire_sheet_hide_row_titles (PsppireSheet *sheet) -{ - 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); - - gtk_widget_hide (sheet->button); - - adjust_scrollbars (sheet); - } - - if (sheet->hadjustment) - g_signal_emit_by_name (sheet->hadjustment, - "value_changed"); -} - - -/* 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 -psppire_sheet_moveto (PsppireSheet *sheet, - gint row, - gint col, - gfloat row_align, - gfloat col_align) -{ - gint width, height; - - g_return_if_fail (row_align >= 0); - g_return_if_fail (col_align >= 0); - - g_return_if_fail (row_align <= 1); - g_return_if_fail (col_align <= 1); - - g_return_if_fail (col < - psppire_axis_unit_count (sheet->haxis)); - g_return_if_fail (row < - psppire_axis_unit_count (sheet->vaxis)); - - gdk_drawable_get_size (sheet->sheet_window, &width, &height); - - - if (row >= 0) - { - gint y = psppire_axis_start_pixel (sheet->vaxis, row); - - gtk_adjustment_set_value (sheet->vadjustment, y - height * row_align); - } - - - if (col >= 0) - { - gint x = psppire_axis_start_pixel (sheet->haxis, col); - - gtk_adjustment_set_value (sheet->hadjustment, x - width * col_align); - } -} - - - - -static gboolean -psppire_sheet_range_isvisible (const PsppireSheet *sheet, - const PsppireSheetRange *range) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - - if (range->row0 < 0 || range->row0 >= psppire_axis_unit_count (sheet->vaxis)) - return FALSE; - - if (range->rowi < 0 || range->rowi >= psppire_axis_unit_count (sheet->vaxis)) - return FALSE; - - if (range->col0 < 0 || range->col0 >= psppire_axis_unit_count (sheet->haxis)) - return FALSE; - - if (range->coli < 0 || range->coli >= psppire_axis_unit_count (sheet->haxis)) - return FALSE; - - if (range->rowi < min_visible_row (sheet)) - return FALSE; - - if (range->row0 > max_visible_row (sheet)) - return FALSE; - - if (range->coli < min_visible_column (sheet)) - return FALSE; - - if (range->col0 > max_visible_column (sheet)) - return FALSE; - - return TRUE; -} - -static gboolean -psppire_sheet_cell_isvisible (PsppireSheet *sheet, - gint row, gint column) -{ - PsppireSheetRange range; - - range.row0 = row; - range.col0 = column; - range.rowi = row; - range.coli = column; - - return psppire_sheet_range_isvisible (sheet, &range); -} - -void -psppire_sheet_get_visible_range (PsppireSheet *sheet, PsppireSheetRange *range) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_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); -} - - -static gboolean -psppire_sheet_set_scroll_adjustments (PsppireSheet *sheet, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment) -{ - if ( sheet->vadjustment != vadjustment ) - { - if (sheet->vadjustment) - g_object_unref (sheet->vadjustment); - sheet->vadjustment = vadjustment; - - if ( vadjustment) - { - g_object_ref (vadjustment); - - g_signal_connect (sheet->vadjustment, "value_changed", - G_CALLBACK (vadjustment_value_changed), - sheet); - } - } - - if ( sheet->hadjustment != hadjustment ) - { - if (sheet->hadjustment) - g_object_unref (sheet->hadjustment); - - sheet->hadjustment = hadjustment; - - if ( hadjustment) - { - g_object_ref (hadjustment); - - g_signal_connect (sheet->hadjustment, "value_changed", - G_CALLBACK (hadjustment_value_changed), - sheet); - } - } - return TRUE; -} - -static void -psppire_sheet_finalize (GObject *object) -{ - PsppireSheet *sheet; - - g_return_if_fail (object != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (object)); - - sheet = PSPPIRE_SHEET (object); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (*G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -static void -psppire_sheet_dispose (GObject *object) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (object); - - g_return_if_fail (object != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (object)); - - if ( sheet->dispose_has_run ) - return ; - - sheet->dispose_has_run = TRUE; - - if ( sheet->cell_padding) - g_boxed_free (GTK_TYPE_BORDER, sheet->cell_padding); - - if (sheet->model) g_object_unref (sheet->model); - if (sheet->vaxis) g_object_unref (sheet->vaxis); - if (sheet->haxis) g_object_unref (sheet->haxis); - - g_object_unref (sheet->button); - sheet->button = NULL; - - /* unref adjustments */ - 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 = NULL; - } - - if (sheet->vadjustment) - { - g_signal_handlers_disconnect_matched (sheet->vadjustment, - G_SIGNAL_MATCH_DATA, - 0, 0, 0, 0, - sheet); - - g_object_unref (sheet->vadjustment); - - sheet->vadjustment = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (*G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -static void -psppire_sheet_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - PsppireSheet *sheet; - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous_style); - - sheet = PSPPIRE_SHEET (widget); - - if (GTK_WIDGET_REALIZED (widget)) - { - gtk_style_set_background (widget->style, widget->window, widget->state); - } - - set_entry_widget_font (sheet); -} - - -static void -psppire_sheet_realize (GtkWidget *widget) -{ - PsppireSheet *sheet; - GdkWindowAttr attributes; - const gint attributes_mask = - GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR; - - GdkGCValues values; - GdkColormap *colormap; - GdkDisplay *display; - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - - sheet = PSPPIRE_SHEET (widget); - - 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.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - - attributes.visual = gtk_widget_get_visual (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.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); - - gdk_window_set_user_data (widget->window, sheet); - - widget->style = gtk_style_attach (widget->style, widget->window); - - 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; - 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); - gdk_window_set_user_data (sheet->column_title_window, sheet); - gtk_style_set_background (widget->style, sheet->column_title_window, - GTK_STATE_NORMAL); - - - attributes.x = 0; - attributes.y = 0; - 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); - gdk_window_set_user_data (sheet->row_title_window, sheet); - gtk_style_set_background (widget->style, sheet->row_title_window, - GTK_STATE_NORMAL); - - /* sheet - window */ - attributes.cursor = gdk_cursor_new_for_display (display, GDK_PLUS); - - attributes.x = 0; - attributes.y = 0; - - 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); - - /* GCs */ - sheet->fg_gc = gdk_gc_new (widget->window); - sheet->bg_gc = gdk_gc_new (widget->window); - - values.foreground = widget->style->white; - values.function = GDK_INVERT; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - values.line_width = MAX (sheet->cell_padding->left, - MAX (sheet->cell_padding->right, - MAX (sheet->cell_padding->top, - sheet->cell_padding->bottom))); - - sheet->xor_gc = gdk_gc_new_with_values (widget->window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_FUNCTION | - GDK_GC_SUBWINDOW | - GDK_GC_LINE_WIDTH - ); - - gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window); - gtk_widget_set_parent (sheet->entry_widget, GTK_WIDGET (sheet)); - - gtk_widget_set_parent_window (sheet->button, sheet->sheet_window); - gtk_widget_set_parent (sheet->button, GTK_WIDGET (sheet)); - - sheet->button->style = gtk_style_attach (sheet->button->style, - sheet->sheet_window); - - - 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); - - sheet->hover_window = create_hover_window (); - - draw_row_title_buttons (sheet); - draw_column_title_buttons (sheet); - - psppire_sheet_update_primary_selection (sheet); - - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); -} - -static void -create_global_button (PsppireSheet *sheet) -{ - sheet->button = gtk_button_new_with_label (" "); - - GTK_WIDGET_UNSET_FLAGS(sheet->button, GTK_CAN_FOCUS); - - g_object_ref_sink (sheet->button); - - g_signal_connect (sheet->button, - "pressed", - G_CALLBACK (global_button_clicked), - sheet); -} - -static void -size_allocate_global_button (PsppireSheet *sheet) -{ - GtkAllocation allocation; - - if (!sheet->column_titles_visible) return; - if (!sheet->row_titles_visible) return; - - gtk_widget_size_request (sheet->button, NULL); - - allocation.x = 0; - allocation.y = 0; - allocation.width = sheet->row_title_area.width; - allocation.height = sheet->column_title_area.height; - - gtk_widget_size_allocate (sheet->button, &allocation); -} - -static void -global_button_clicked (GtkWidget *widget, gpointer data) -{ - psppire_sheet_click_cell (PSPPIRE_SHEET (data), -1, -1); -} - - -static void -psppire_sheet_unrealize (GtkWidget *widget) -{ - PsppireSheet *sheet; - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - - sheet = PSPPIRE_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); - - gtk_widget_unparent (sheet->entry_widget); - if (sheet->button != NULL) - gtk_widget_unparent (sheet->button); - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); -} - -static void -psppire_sheet_map (GtkWidget *widget) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - - if (!GTK_WIDGET_MAPPED (widget)) - { - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); - - gdk_window_show (widget->window); - gdk_window_show (sheet->sheet_window); - - if (sheet->column_titles_visible) - { - draw_column_title_buttons (sheet); - gdk_window_show (sheet->column_title_window); - } - if (sheet->row_titles_visible) - { - draw_row_title_buttons (sheet); - gdk_window_show (sheet->row_title_window); - } - - if (!GTK_WIDGET_MAPPED (sheet->entry_widget) - && sheet->active_cell.row >= 0 - && sheet->active_cell.col >= 0 ) - { - gtk_widget_show (sheet->entry_widget); - gtk_widget_map (sheet->entry_widget); - } - - if (!GTK_WIDGET_MAPPED (sheet->button)) - { - gtk_widget_show (sheet->button); - gtk_widget_map (sheet->button); - } - - redraw_range (sheet, NULL); - change_active_cell (sheet, - sheet->active_cell.row, - sheet->active_cell.col); - } -} - -static void -psppire_sheet_unmap (GtkWidget *widget) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - if (!GTK_WIDGET_MAPPED (widget)) - return; - - 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); - - gtk_widget_unmap (sheet->entry_widget); - gtk_widget_unmap (sheet->button); - gtk_widget_unmap (sheet->hover_window->window); -} - -/* get cell attributes of the given cell */ -/* TRUE means that the cell is currently allocated */ -static gboolean psppire_sheet_get_attributes (const PsppireSheet *sheet, - gint row, gint col, - PsppireSheetCellAttr *attributes); - - - -static void -psppire_sheet_cell_draw (PsppireSheet *sheet, gint row, gint col) -{ - PangoLayout *layout; - PangoRectangle text; - PangoFontDescription *font_desc = GTK_WIDGET (sheet)->style->font_desc; - gint font_height; - - gchar *label; - - PsppireSheetCellAttr attributes; - GdkRectangle area; - - g_return_if_fail (sheet != NULL); - - /* bail now if we aren't yet drawable */ - if (!GTK_WIDGET_DRAWABLE (sheet)) return; - - if (row < 0 || - row >= psppire_axis_unit_count (sheet->vaxis)) - return; - - if (col < 0 || - col >= psppire_axis_unit_count (sheet->haxis)) - return; - - psppire_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); - - 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->color[GRID_COLOR]); - - gdk_draw_rectangle (sheet->sheet_window, - sheet->bg_gc, - FALSE, - area.x, area.y, - area.width, area.height); - } - - - label = psppire_sheet_cell_get_text (sheet, row, col); - if (NULL == label) - return; - - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), label); - dispose_string (sheet, label); - - - pango_layout_set_font_description (layout, font_desc); - - pango_layout_get_pixel_extents (layout, NULL, &text); - - gdk_gc_set_clip_rectangle (sheet->fg_gc, &area); - - font_height = pango_font_description_get_size (font_desc); - if ( !pango_font_description_get_size_is_absolute (font_desc)) - font_height /= PANGO_SCALE; - - - if ( sheet->cell_padding ) - { - area.x += sheet->cell_padding->left; - area.width -= sheet->cell_padding->right - + sheet->cell_padding->left; - - area.y += sheet->cell_padding->top; - area.height -= sheet->cell_padding->bottom - + - sheet->cell_padding->top; - } - - /* Centre the text vertically */ - area.y += (area.height - font_height) / 2.0; - - switch (attributes.justification) - { - case GTK_JUSTIFY_RIGHT: - area.x += area.width - text.width; - break; - case GTK_JUSTIFY_CENTER: - area.x += (area.width - text.width) / 2.0; - break; - case GTK_JUSTIFY_LEFT: - /* Do nothing */ - break; - default: - g_critical ("Unhandled justification %d in column %d\n", - attributes.justification, col); - break; - } - - gdk_draw_layout (sheet->sheet_window, sheet->fg_gc, - area.x, - area.y, - layout); - - gdk_gc_set_clip_rectangle (sheet->fg_gc, NULL); - g_object_unref (layout); -} - - -static void -draw_sheet_region (PsppireSheet *sheet, GdkRegion *region) -{ - PsppireSheetRange range; - GdkRectangle area; - gint y, x; - gint i, j; - - PsppireSheetRange drawing_range; - - gdk_region_get_clipbox (region, &area); - - y = area.y + sheet->vadjustment->value; - x = 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); - - range.row0 = row_from_ypixel (sheet, y); - range.rowi = row_from_ypixel (sheet, y + area.height); - - range.col0 = column_from_xpixel (sheet, x); - range.coli = column_from_xpixel (sheet, x + area.width); - - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_SHEET (sheet)); - - if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (sheet))) return; - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return; - - - 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)); - - g_return_if_fail (drawing_range.rowi >= drawing_range.row0); - g_return_if_fail (drawing_range.coli >= drawing_range.col0); - - for (i = drawing_range.row0; i <= drawing_range.rowi; i++) - { - for (j = drawing_range.col0; j <= drawing_range.coli; j++) - psppire_sheet_cell_draw (sheet, i, j); - } - - if (sheet->select_status == PSPPIRE_SHEET_NORMAL && - sheet->active_cell.row >= drawing_range.row0 && - sheet->active_cell.row <= drawing_range.rowi && - sheet->active_cell.col >= drawing_range.col0 && - sheet->active_cell.col <= drawing_range.coli) - psppire_sheet_show_entry_widget (sheet); -} - -static void -psppire_sheet_set_cell (PsppireSheet *sheet, gint row, gint col, - GtkJustification justification, - const gchar *text) -{ - PsppireSheetModel *model ; - gchar *old_text ; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (col >= psppire_axis_unit_count (sheet->haxis) - || row >= psppire_axis_unit_count (sheet->vaxis)) - return; - - if (col < 0 || row < 0) return; - - model = psppire_sheet_get_model (sheet); - - old_text = psppire_sheet_model_get_string (model, row, col); - - if (0 != g_strcmp0 (old_text, text)) - { - g_signal_handler_block (sheet->model, sheet->update_handler_id); - psppire_sheet_model_set_string (model, text, row, col); - g_signal_handler_unblock (sheet->model, sheet->update_handler_id); - } - - if ( psppire_sheet_model_free_strings (model)) - g_free (old_text); -} - - -void -psppire_sheet_cell_clear (PsppireSheet *sheet, gint row, gint column) -{ - PsppireSheetRange range; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - 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); - - psppire_sheet_real_cell_clear (sheet, row, column); - - redraw_range (sheet, &range); -} - -static void -psppire_sheet_real_cell_clear (PsppireSheet *sheet, gint row, gint column) -{ - PsppireSheetModel *model = psppire_sheet_get_model (sheet); - - gchar *old_text = psppire_sheet_cell_get_text (sheet, row, column); - - if (old_text && strlen (old_text) > 0 ) - { - psppire_sheet_model_datum_clear (model, row, column); - } - - dispose_string (sheet, old_text); -} - -gchar * -psppire_sheet_cell_get_text (const PsppireSheet *sheet, gint row, gint col) -{ - PsppireSheetModel *model; - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), NULL); - - if (col >= psppire_axis_unit_count (sheet->haxis) || row >= psppire_axis_unit_count (sheet->vaxis)) - return NULL; - if (col < 0 || row < 0) return NULL; - - model = psppire_sheet_get_model (sheet); - - if ( !model ) - return NULL; - - return psppire_sheet_model_get_string (model, row, col); -} - - -/* Convert X, Y (in pixels) to *ROW, *COLUMN - If the function returns FALSE, then the results will be unreliable. -*/ -static gboolean -psppire_sheet_get_pixel_info (PsppireSheet *sheet, - gint x, - gint y, - gint *row, - gint *column) -{ - gint trow, tcol; - *row = -G_MAXINT; - *column = -G_MAXINT; - - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), 0); - - /* bounds checking, return false if the user clicked - on a blank area */ - if (y < 0) - return FALSE; - - if (x < 0) - return FALSE; - - 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 > psppire_axis_unit_count (sheet->vaxis)) - return FALSE; - } - - *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 > psppire_axis_unit_count (sheet->haxis)) - return FALSE; - } - - *column = tcol; - - return TRUE; -} - -gboolean -psppire_sheet_get_cell_area (PsppireSheet *sheet, - gint row, - gint column, - GdkRectangle *area) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), 0); - - if (row >= psppire_axis_unit_count (sheet->vaxis) || column >= psppire_axis_unit_count (sheet->haxis)) - return FALSE; - - 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 - : psppire_axis_unit_size (sheet->haxis, column); - - area->height= (row == -1) ? sheet->column_title_area.height - : psppire_axis_unit_size (sheet->vaxis, row); - - return TRUE; -} - -void -psppire_sheet_set_active_cell (PsppireSheet *sheet, gint row, gint col) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (row < -1 || col < -1) - return; - - if (row >= psppire_axis_unit_count (sheet->vaxis) - || - col >= psppire_axis_unit_count (sheet->haxis)) - return; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - if ( row == -1 || col == -1) - { - psppire_sheet_hide_entry_widget (sheet); - return; - } - - change_active_cell (sheet, row, col); -} - -void -psppire_sheet_get_active_cell (PsppireSheet *sheet, gint *row, gint *column) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if ( row ) *row = sheet->active_cell.row; - if (column) *column = sheet->active_cell.col; -} - -static void -entry_load_text (PsppireSheet *sheet) -{ - gint row, col; - const char *text; - GtkJustification justification; - PsppireSheetCellAttr attributes; - - if (!GTK_WIDGET_VISIBLE (sheet->entry_widget)) return; - if (sheet->select_status != PSPPIRE_SHEET_NORMAL) return; - - row = sheet->active_cell.row; - col = sheet->active_cell.col; - - if (row < 0 || col < 0) return; - - text = gtk_entry_get_text (psppire_sheet_get_entry (sheet)); - - if (text && strlen (text) > 0) - { - psppire_sheet_get_attributes (sheet, row, col, &attributes); - justification = attributes.justification; - psppire_sheet_set_cell (sheet, row, col, justification, text); - } -} - - -static void -psppire_sheet_hide_entry_widget (PsppireSheet *sheet) -{ - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - if (sheet->active_cell.row < 0 || - sheet->active_cell.col < 0) return; - - gtk_widget_hide (sheet->entry_widget); - gtk_widget_unmap (sheet->entry_widget); - - GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE); -} - -static void -change_active_cell (PsppireSheet *sheet, gint row, gint col) -{ - gint old_row, old_col; - - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (row < 0 || col < 0) - return; - - if ( row > psppire_axis_unit_count (sheet->vaxis) - || col > psppire_axis_unit_count (sheet->haxis)) - return; - - old_row = sheet->active_cell.row; - old_col = sheet->active_cell.col; - - entry_load_text (sheet); - - /* Erase the old cell border */ - psppire_sheet_draw_active_cell (sheet); - - sheet->active_cell.row = row; - sheet->active_cell.col = col; - - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - - GTK_WIDGET_UNSET_FLAGS (sheet->entry_widget, GTK_HAS_FOCUS); - - psppire_sheet_draw_active_cell (sheet); - psppire_sheet_show_entry_widget (sheet); - - GTK_WIDGET_SET_FLAGS (sheet->entry_widget, GTK_HAS_FOCUS); - - g_signal_emit (sheet, sheet_signals [ACTIVATE], 0, - row, col, old_row, old_col); - -} - -static void -psppire_sheet_show_entry_widget (PsppireSheet *sheet) -{ - GtkEntry *sheet_entry; - PsppireSheetCellAttr attributes; - - gint row, col; - - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - row = sheet->active_cell.row; - col = sheet->active_cell.col; - - /* Don't show the active cell, if there is no active cell: */ - if (! (row >= 0 && col >= 0)) /* e.g row or coll == -1. */ - return; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (sheet->select_status != PSPPIRE_SHEET_NORMAL) return; - if (PSPPIRE_SHEET_IN_SELECTION (sheet)) return; - - GTK_WIDGET_SET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE); - - sheet_entry = psppire_sheet_get_entry (sheet); - - psppire_sheet_get_attributes (sheet, row, col, &attributes); - - if (GTK_IS_ENTRY (sheet_entry)) - { - gchar *text = psppire_sheet_cell_get_text (sheet, row, col); - const gchar *old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry)); - - if ( ! text ) - text = g_strdup (""); - - if (strcmp (old_text, text) != 0) - gtk_entry_set_text (sheet_entry, text); - - dispose_string (sheet, 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; - } - } - } - - psppire_sheet_size_allocate_entry (sheet); - - gtk_widget_set_sensitive (GTK_WIDGET (sheet_entry), - psppire_sheet_model_is_editable (sheet->model, - row, col)); - gtk_widget_map (sheet->entry_widget); -} - -static gboolean -psppire_sheet_draw_active_cell (PsppireSheet *sheet) -{ - gint row, col; - PsppireSheetRange range; - - row = sheet->active_cell.row; - col = sheet->active_cell.col; - - if (row < 0 || col < 0) return FALSE; - - if (!psppire_sheet_cell_isvisible (sheet, row, col)) - return FALSE; - - range.col0 = range.coli = col; - range.row0 = range.rowi = row; - - psppire_sheet_draw_border (sheet, range); - - return FALSE; -} - - - -static void -psppire_sheet_draw_border (PsppireSheet *sheet, PsppireSheetRange new_range) -{ - GdkRectangle area; - - rectangle_from_range (sheet, &new_range, &area); - - area.width ++; - area.height ++; - - gdk_gc_set_clip_rectangle (sheet->xor_gc, &area); - - area.x += sheet->cell_padding->left / 2; - area.y += sheet->cell_padding->top / 2; - area.width -= (sheet->cell_padding->left + sheet->cell_padding->right ) / 2; - area.height -= (sheet->cell_padding->top + sheet->cell_padding->bottom ) / 2; - - gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, - FALSE, - area.x, - area.y, - area.width, - area.height); - - gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL); -} - - - -/* Selection related functions */ - -void -psppire_sheet_select_row (PsppireSheet *sheet, gint row) -{ - GdkRectangle area; - sheet->select_status = PSPPIRE_SHEET_ROW_SELECTED; - - sheet->range.col0 = sheet->range.coli = -1; - sheet->range.row0 = sheet->range.rowi = row; - - rectangle_from_range (sheet, &sheet->range, &area); - area.x++; - area.y++; - - gdk_window_invalidate_rect (sheet->sheet_window, &area, FALSE); - - g_signal_emit (sheet, sheet_signals [SELECT_ROW], 0, row); -} - -void -psppire_sheet_select_column (PsppireSheet *sheet, gint column) -{ - GdkRectangle area; - sheet->select_status = PSPPIRE_SHEET_COLUMN_SELECTED; - - sheet->range.col0 = sheet->range.coli = column; - sheet->range.row0 = sheet->range.rowi = -1; - - rectangle_from_range (sheet, &sheet->range, &area); - area.x++; - area.y++; - - gdk_window_invalidate_rect (sheet->sheet_window, &area, FALSE); - - g_signal_emit (sheet, sheet_signals [SELECT_COLUMN], 0, column); -} - - -void -psppire_sheet_select_range (PsppireSheet *sheet, const PsppireSheetRange *range) -{ - GdkRectangle area; - sheet->select_status = PSPPIRE_SHEET_RANGE_SELECTED; - - sheet->range = *range; - - rectangle_from_range (sheet, range, &area); - area.x++; - area.y++; - gdk_window_invalidate_rect (sheet->sheet_window, &area, FALSE); -} - - -void -psppire_sheet_unselect_range (PsppireSheet *sheet) -{ - sheet->select_status = PSPPIRE_SHEET_NORMAL; - - if (sheet->sheet_window != NULL) - { - GdkRectangle area; - - rectangle_from_range (sheet, &sheet->range, &area); - area.x++; - area.y++; - gdk_window_invalidate_rect (sheet->sheet_window, &area, FALSE); - } - - g_signal_emit (sheet, sheet_signals [SELECT_COLUMN], 0, -1); - g_signal_emit (sheet, sheet_signals [SELECT_ROW], 0, -1); -} - -void -psppire_sheet_get_selected_range (PsppireSheet *sheet, PsppireSheetRange *range) -{ - g_return_if_fail (sheet != NULL); - *range = sheet->range; -} - - -static gint -psppire_sheet_expose (GtkWidget *widget, GdkEventExpose *event) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - g_return_val_if_fail (event != NULL, FALSE); - - if (!GTK_WIDGET_DRAWABLE (widget)) - return FALSE; - - /* exposure events on the sheet */ - if (event->window == sheet->row_title_window && - sheet->row_titles_visible) - { - 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) - { - draw_column_title_buttons_range (sheet, - min_visible_column (sheet), - max_visible_column (sheet)); - } - - if (event->window == sheet->sheet_window) - { - draw_sheet_region (sheet, event->region); - - if (sheet->select_status != PSPPIRE_SHEET_NORMAL) - { - GdkRectangle area; - - rectangle_from_range (sheet, &sheet->range, &area); - - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - area.x + 1, area.y + 1, - area.width, area.height); - } - - - if ((!PSPPIRE_SHEET_IN_XDRAG (sheet)) && (!PSPPIRE_SHEET_IN_YDRAG (sheet))) - { - GdkRectangle rect; - PsppireSheetRange range; - range.row0 = range.rowi = sheet->active_cell.row; - range.col0 = range.coli = sheet->active_cell.col; - - rectangle_from_range (sheet, &range, &rect); - - if (GDK_OVERLAP_RECTANGLE_OUT != - gdk_region_rect_in (event->region, &rect)) - { - psppire_sheet_draw_active_cell (sheet); - } - } - - } - - (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); - - return FALSE; -} - - -static gboolean -psppire_sheet_button_press (GtkWidget *widget, GdkEventButton *event) -{ - PsppireSheet *sheet; - GdkModifierType mods; - gint x, y; - gint row, column; - - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (PSPPIRE_IS_SHEET (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - sheet = PSPPIRE_SHEET (widget); - - /* Cancel any pending tooltips */ - if (sheet->motion_timer) - { - g_source_remove (sheet->motion_timer); - sheet->motion_timer = 0; - } - - gtk_widget_get_pointer (widget, &x, &y); - psppire_sheet_get_pixel_info (sheet, x, y, &row, &column); - - - 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 (psppire_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); - } - } - - if (event->window == sheet->row_title_window) - { - g_signal_emit (sheet, - sheet_signals[BUTTON_EVENT_ROW], 0, - row, event); - - if (psppire_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) - { - sheet->x_drag = event->x; - - if (on_column_boundary (sheet, sheet->x_drag, &sheet->drag_cell.col)) - { - PSPPIRE_SHEET_SET_FLAGS (sheet, PSPPIRE_SHEET_IN_XDRAG); - gdk_pointer_grab (sheet->column_title_window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time); - - draw_xor_vline (sheet); - return TRUE; - } - } - - if (event->window == sheet->row_title_window) - { - sheet->y_drag = event->y; - - if (on_row_boundary (sheet, sheet->y_drag, &sheet->drag_cell.row)) - { - PSPPIRE_SHEET_SET_FLAGS (sheet, PSPPIRE_SHEET_IN_YDRAG); - gdk_pointer_grab (sheet->row_title_window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time); - - draw_xor_hline (sheet); - return TRUE; - } - } - - /* the sheet itself does not handle other than single click events */ - if (event->type != GDK_BUTTON_PRESS) return FALSE; - - /* selections on the sheet */ - if (event->window == sheet->sheet_window) - { - gtk_widget_get_pointer (widget, &x, &y); - psppire_sheet_get_pixel_info (sheet, x, y, &row, &column); - gdk_pointer_grab (sheet->sheet_window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time); - gtk_grab_add (GTK_WIDGET (sheet)); - - if ( sheet->select_status == PSPPIRE_SHEET_NORMAL) - { - sheet->range.row0 = row; - sheet->range.col0 = column; - } - else - { - psppire_sheet_unselect_range (sheet); - } - psppire_sheet_click_cell (sheet, row, column); - } - - if (event->window == sheet->column_title_window) - { - gtk_widget_get_pointer (widget, &x, &y); - if ( sheet->row_titles_visible) - x -= sheet->row_title_area.width; - - x += sheet->hadjustment->value; - - column = column_from_xpixel (sheet, x); - - if (psppire_sheet_model_get_column_sensitivity (sheet->model, column)) - { - gtk_grab_add (GTK_WIDGET (sheet)); - PSPPIRE_SHEET_SET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - } - } - - if (event->window == sheet->row_title_window) - { - gtk_widget_get_pointer (widget, &x, &y); - if ( sheet->column_titles_visible) - y -= sheet->column_title_area.height; - - y += sheet->vadjustment->value; - - row = row_from_ypixel (sheet, y); - if (psppire_sheet_model_get_row_sensitivity (sheet->model, row)) - { - gtk_grab_add (GTK_WIDGET (sheet)); - PSPPIRE_SHEET_SET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - } - } - - return TRUE; -} - -static gboolean -psppire_sheet_click_cell (PsppireSheet *sheet, gint row, gint column) -{ - PsppireSheetCell cell; - gboolean forbid_move; - - cell.row = row; - cell.col = column; - - if (row >= psppire_axis_unit_count (sheet->vaxis) - || column >= psppire_axis_unit_count (sheet->haxis)) - { - return FALSE; - } - - g_signal_emit (sheet, sheet_signals[TRAVERSE], 0, - &sheet->active_cell, - &cell, - &forbid_move); - - if (forbid_move) - { - if (sheet->select_status == PSPPIRE_SHEET_NORMAL) - return FALSE; - - row = sheet->active_cell.row; - column = sheet->active_cell.col; - - change_active_cell (sheet, row, column); - return FALSE; - } - - if (row == -1 && column >= 0) - { - psppire_sheet_select_column (sheet, column); - return TRUE; - } - - if (column == -1 && row >= 0) - { - psppire_sheet_select_row (sheet, row); - return TRUE; - } - - if (row == -1 && column == -1) - { - sheet->range.row0 = 0; - sheet->range.col0 = 0; - sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1; - sheet->range.coli = psppire_axis_unit_count (sheet->haxis) - 1; - return TRUE; - } - - if (sheet->select_status == PSPPIRE_SHEET_NORMAL) - change_active_cell (sheet, row, column); - - gtk_widget_grab_focus (GTK_WIDGET (sheet->entry_widget)); - - return TRUE; -} - -static gint -psppire_sheet_button_release (GtkWidget *widget, - GdkEventButton *event) -{ - GdkDisplay *display = gtk_widget_get_display (widget); - - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - /* release on resize windows */ - if (PSPPIRE_SHEET_IN_XDRAG (sheet)) - { - gint width; - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_XDRAG); - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - - gdk_display_pointer_ungrab (display, event->time); - draw_xor_vline (sheet); - - 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 (PSPPIRE_SHEET_IN_YDRAG (sheet)) - { - gint height; - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_YDRAG); - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - - gdk_display_pointer_ungrab (display, event->time); - draw_xor_hline (sheet); - - 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 (PSPPIRE_SHEET_IN_DRAG (sheet)) - { - PsppireSheetRange old_range; - draw_xor_rectangle (sheet, sheet->drag_range); - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_DRAG); - gdk_display_pointer_ungrab (display, event->time); - - psppire_sheet_unselect_range (sheet); - - old_range = sheet->range; - sheet->range = sheet->drag_range; - sheet->drag_range = old_range; - g_signal_emit (sheet, sheet_signals[MOVE_RANGE], 0, - &sheet->drag_range, &sheet->range); - psppire_sheet_select_range (sheet, &sheet->range); - } - - if (PSPPIRE_SHEET_IN_SELECTION (sheet)) - { - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - sheet->select_status = PSPPIRE_SHEET_RANGE_SELECTED; - - change_active_cell (sheet, sheet->active_cell.row, - sheet->active_cell.col); - } - - gdk_display_pointer_ungrab (display, event->time); - gtk_grab_remove (GTK_WIDGET (sheet)); - - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - - return TRUE; -} - - - - - -/* Shamelessly lifted from gtktooltips */ -static gboolean -psppire_sheet_subtitle_paint_window (GtkWidget *tip_window) -{ - GtkRequisition req; - - gtk_widget_size_request (tip_window, &req); - gtk_paint_flat_box (tip_window->style, tip_window->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - NULL, GTK_WIDGET(tip_window), "tooltip", - 0, 0, req.width, req.height); - - return FALSE; -} - -static void -destroy_hover_window (PsppireSheetHoverTitle *h) -{ - gtk_widget_destroy (h->window); - g_free (h); -} - -static PsppireSheetHoverTitle * -create_hover_window (void) -{ - PsppireSheetHoverTitle *hw = g_malloc (sizeof (*hw)); - - hw->window = gtk_window_new (GTK_WINDOW_POPUP); - -#if GTK_CHECK_VERSION (2, 9, 0) - gtk_window_set_type_hint (GTK_WINDOW (hw->window), - GDK_WINDOW_TYPE_HINT_TOOLTIP); -#endif - - gtk_widget_set_app_paintable (hw->window, TRUE); - gtk_window_set_resizable (GTK_WINDOW (hw->window), FALSE); - gtk_widget_set_name (hw->window, "gtk-tooltips"); - gtk_container_set_border_width (GTK_CONTAINER (hw->window), 4); - - g_signal_connect (hw->window, - "expose_event", - G_CALLBACK (psppire_sheet_subtitle_paint_window), - NULL); - - hw->label = gtk_label_new (NULL); - - - gtk_label_set_line_wrap (GTK_LABEL (hw->label), TRUE); - gtk_misc_set_alignment (GTK_MISC (hw->label), 0.5, 0.5); - - gtk_container_add (GTK_CONTAINER (hw->window), hw->label); - - gtk_widget_show (hw->label); - - g_signal_connect (hw->window, - "destroy", - G_CALLBACK (gtk_widget_destroyed), - &hw->window); - - return hw; -} - -#define HOVER_WINDOW_Y_OFFSET 2 - -static void -show_subtitle (PsppireSheet *sheet, gint row, gint column, - const gchar *subtitle) -{ - gint x, y; - gint px, py; - gint width; - - if ( ! subtitle ) - return; - - gtk_label_set_text (GTK_LABEL (sheet->hover_window->label), - subtitle); - - - sheet->hover_window->row = row; - sheet->hover_window->column = column; - - gdk_window_get_origin (GTK_WIDGET (sheet)->window, &x, &y); - - gtk_widget_get_pointer (GTK_WIDGET (sheet), &px, &py); - - gtk_widget_show (sheet->hover_window->window); - - width = GTK_WIDGET (sheet->hover_window->label)->allocation.width; - - if (row == -1 ) - { - x += px; - x -= width / 2; - y += sheet->column_title_area.y; - y += sheet->column_title_area.height; - y += HOVER_WINDOW_Y_OFFSET; - } - - if ( column == -1 ) - { - y += py; - x += sheet->row_title_area.x; - x += sheet->row_title_area.width * 2 / 3.0; - } - - gtk_window_move (GTK_WINDOW (sheet->hover_window->window), - x, y); -} - -static gboolean -motion_timeout_callback (gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - gint x, y; - gint row, column; - - gdk_threads_enter (); - gtk_widget_get_pointer (GTK_WIDGET (sheet), &x, &y); - - if ( psppire_sheet_get_pixel_info (sheet, x, y, &row, &column) ) - { - if (sheet->row_title_under && row >= 0) - { - gchar *text = psppire_sheet_model_get_row_subtitle (sheet->model, row); - - show_subtitle (sheet, row, -1, text); - g_free (text); - } - - if (sheet->column_title_under && column >= 0) - { - gchar *text = psppire_sheet_model_get_column_subtitle (sheet->model, - column); - - show_subtitle (sheet, -1, column, text); - - g_free (text); - } - } - - gdk_threads_leave (); - return FALSE; -} - -static gboolean -psppire_sheet_motion (GtkWidget *widget, GdkEventMotion *event) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - GdkModifierType mods; - GdkCursorType new_cursor; - gint x, y; - gint row, column; - GdkDisplay *display; - - g_return_val_if_fail (event != NULL, FALSE); - - display = gtk_widget_get_display (widget); - - /* selections on the sheet */ - x = event->x; - y = event->y; - - 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); - } - else - { - gint row, column; - gint wx, wy; - gtk_widget_get_pointer (widget, &wx, &wy); - - if ( psppire_sheet_get_pixel_info (sheet, wx, wy, &row, &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) - { - if (!PSPPIRE_SHEET_IN_SELECTION (sheet) && - 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_for_display (display, new_cursor); - - gdk_window_set_cursor (sheet->column_title_window, - sheet->cursor_drag); - } - } - else - { - new_cursor = GDK_TOP_LEFT_ARROW; - if (!PSPPIRE_SHEET_IN_XDRAG (sheet) && - new_cursor != sheet->cursor_drag->type) - { - gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = - gdk_cursor_new_for_display (display, new_cursor); - gdk_window_set_cursor (sheet->column_title_window, - sheet->cursor_drag); - } - } - } - else if (event->window == sheet->row_title_window) - { - if (!PSPPIRE_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_for_display (display, new_cursor); - gdk_window_set_cursor (sheet->row_title_window, - sheet->cursor_drag); - } - } - else - { - new_cursor = GDK_TOP_LEFT_ARROW; - if (!PSPPIRE_SHEET_IN_YDRAG (sheet) && - new_cursor != sheet->cursor_drag->type) - { - gdk_cursor_unref (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 = GDK_PLUS; - if ( event->window == sheet->sheet_window && - !POSSIBLE_DRAG (sheet, x, y, &row, &column) && - !PSPPIRE_SHEET_IN_DRAG (sheet) && - !POSSIBLE_RESIZE (sheet, x, y, &row, &column) && - new_cursor != sheet->cursor_drag->type) - { - gdk_cursor_unref (sheet->cursor_drag); - 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) ) && - (POSSIBLE_DRAG (sheet, x, y, &row, &column) || - PSPPIRE_SHEET_IN_DRAG (sheet)) && - new_cursor != sheet->cursor_drag->type) - { - gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW); - gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag); - } - - gdk_window_get_pointer (widget->window, &x, &y, &mods); - if (! (mods & GDK_BUTTON1_MASK)) return FALSE; - - if (PSPPIRE_SHEET_IN_XDRAG (sheet)) - { - if (event->x != sheet->x_drag) - { - draw_xor_vline (sheet); - sheet->x_drag = event->x; - draw_xor_vline (sheet); - } - - return TRUE; - } - - if (PSPPIRE_SHEET_IN_YDRAG (sheet)) - { - if (event->y != sheet->y_drag) - { - draw_xor_hline (sheet); - sheet->y_drag = event->y; - draw_xor_hline (sheet); - } - - return TRUE; - } - - if (PSPPIRE_SHEET_IN_DRAG (sheet)) - { - PsppireSheetRange aux; - column = column_from_xpixel (sheet, x)- sheet->drag_cell.col; - row = row_from_ypixel (sheet, y) - sheet->drag_cell.row; - if (sheet->select_status == PSPPIRE_SHEET_COLUMN_SELECTED) row = 0; - if (sheet->select_status == PSPPIRE_SHEET_ROW_SELECTED) column = 0; - sheet->x_drag = x; - sheet->y_drag = y; - aux = sheet->range; - 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; - sheet->drag_range.col0 = sheet->range.col0 + column; - sheet->drag_range.rowi = sheet->range.rowi + row; - sheet->drag_range.coli = sheet->range.coli + column; - if (aux.row0 != sheet->drag_range.row0 || - aux.col0 != sheet->drag_range.col0) - { - draw_xor_rectangle (sheet, aux); - draw_xor_rectangle (sheet, sheet->drag_range); - } - } - return TRUE; - } - - psppire_sheet_get_pixel_info (sheet, x, y, &row, &column); - - if (sheet->select_status == PSPPIRE_SHEET_NORMAL && row == sheet->active_cell.row && - column == sheet->active_cell.col) return TRUE; - - if ( mods & GDK_BUTTON1_MASK) - { - if (PSPPIRE_SHEET_IN_SELECTION (sheet) ) - { - /* Redraw the old range */ - psppire_sheet_unselect_range (sheet); - - sheet->range.rowi = row; - sheet->range.coli = column; - - /* Redraw the new range */ - psppire_sheet_select_range (sheet, &sheet->range); - } - else - { - PSPPIRE_SHEET_SET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - } - } - - return TRUE; -} - -static gboolean -psppire_sheet_crossing_notify (GtkWidget *widget, - GdkEventCrossing *event) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - 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; - - if (event->type == GDK_LEAVE_NOTIFY) - gtk_widget_hide (sheet->hover_window->window); - - return TRUE; -} - - -static gboolean -psppire_sheet_focus_in (GtkWidget *w, - GdkEventFocus *event) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (w); - - gtk_widget_grab_focus (sheet->entry_widget); - - return TRUE; -} - - - -static gint -psppire_sheet_entry_key_press (GtkWidget *widget, - GdkEventKey *key) -{ - gboolean focus; - g_signal_emit_by_name (widget, "key_press_event", key, &focus); - return focus; -} - - -/* Number of rows in a step-increment */ -#define ROWS_PER_STEP 1 - - -static void -page_vertical (PsppireSheet *sheet, GtkScrollType dir) -{ - gint old_row = sheet->active_cell.row ; - glong vpixel = psppire_axis_start_pixel (sheet->vaxis, old_row); - - gint new_row; - - vpixel -= psppire_axis_start_pixel (sheet->vaxis, - min_visible_row (sheet)); - - switch ( dir) - { - case GTK_SCROLL_PAGE_DOWN: - gtk_adjustment_set_value (sheet->vadjustment, - sheet->vadjustment->value + - sheet->vadjustment->page_increment); - break; - case GTK_SCROLL_PAGE_UP: - gtk_adjustment_set_value (sheet->vadjustment, - sheet->vadjustment->value - - sheet->vadjustment->page_increment); - - break; - default: - g_assert_not_reached (); - break; - } - - - 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 (PsppireSheet *sheet, GtkScrollType dir) -{ - gint current_row = sheet->active_cell.row; - gint current_col = sheet->active_cell.col; - PsppireSheetCell 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 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; - case GTK_SCROLL_STEP_FORWARD: - new_cell.col++; - if (new_cell.col >= - psppire_sheet_model_get_column_count (sheet->model)) - { - new_cell.col = 0; - new_cell.row++; - } - break; - case GTK_SCROLL_STEP_BACKWARD: - new_cell.col--; - if (new_cell.col < 0) - { - new_cell.col = - psppire_sheet_model_get_column_count (sheet->model) - 1; - new_cell.row--; - } - 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 -psppire_sheet_key_press (GtkWidget *widget, - GdkEventKey *key) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (widget); - - PSPPIRE_SHEET_UNSET_FLAGS (sheet, PSPPIRE_SHEET_IN_SELECTION); - - switch (key->keyval) - { - case GDK_Tab: - step_sheet (sheet, GTK_SCROLL_STEP_FORWARD); - break; - case GDK_Right: - step_sheet (sheet, GTK_SCROLL_STEP_RIGHT); - break; - case GDK_ISO_Left_Tab: - step_sheet (sheet, GTK_SCROLL_STEP_BACKWARD); - break; - case GDK_Left: - 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: - gtk_adjustment_set_value (sheet->vadjustment, - sheet->vadjustment->lower); - - change_active_cell (sheet, 0, - sheet->active_cell.col); - - break; - - case GDK_End: - 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: - psppire_sheet_real_cell_clear (sheet, sheet->active_cell.row, sheet->active_cell.col); - break; - default: - return FALSE; - break; - } - - return TRUE; -} - -static void -psppire_sheet_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - PsppireSheet *sheet; - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - g_return_if_fail (requisition != NULL); - - sheet = PSPPIRE_SHEET (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) - requisition->height += sheet->column_title_area.height; - - /* compute the size of the row title area */ - if (sheet->row_titles_visible) - requisition->width += sheet->row_title_area.width; -} - - -static void -psppire_sheet_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - PsppireSheet *sheet; - GtkAllocation sheet_allocation; - gint border_width; - - g_return_if_fail (widget != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (widget)); - g_return_if_fail (allocation != NULL); - - sheet = PSPPIRE_SHEET (widget); - widget->allocation = *allocation; - border_width = GTK_CONTAINER (widget)->border_width; - - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x + border_width, - allocation->y + border_width, - allocation->width - 2 * border_width, - 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; - - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (sheet->sheet_window, - sheet_allocation.x, - sheet_allocation.y, - sheet_allocation.width, - sheet_allocation.height); - - /* 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; - - 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.y, - sheet->column_title_area.width, - sheet->column_title_area.height); - - - if (GTK_WIDGET_REALIZED (widget) && sheet->row_titles_visible) - gdk_window_move_resize (sheet->row_title_window, - sheet->row_title_area.x, - sheet->row_title_area.y, - sheet->row_title_area.width, - sheet->row_title_area.height); - - size_allocate_global_button (sheet); - - 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; - - g_object_set (sheet->vaxis, - "minimum-extent", height, - NULL); - } - - - /* set the scrollbars adjustments */ - adjust_scrollbars (sheet); -} - -static void -draw_column_title_buttons (PsppireSheet *sheet) -{ - gint x, width; - - if (!sheet->column_titles_visible) return; - if (!GTK_WIDGET_REALIZED (sheet)) - return; - - gdk_drawable_get_size (sheet->sheet_window, &width, NULL); - x = 0; - - if (sheet->row_titles_visible) - { - x = sheet->row_title_area.width; - } - - if (sheet->column_title_area.width != width || sheet->column_title_area.x != x) - { - sheet->column_title_area.width = width; - sheet->column_title_area.x = x; - 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); - } - - 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, - sheet->column_title_area.height); - - if (!GTK_WIDGET_DRAWABLE (sheet)) return; - - draw_column_title_buttons_range (sheet, min_visible_column (sheet), - max_visible_column (sheet)); -} - -static void -draw_row_title_buttons (PsppireSheet *sheet) -{ - gint y = 0; - gint height; - - if (!sheet->row_titles_visible) return; - if (!GTK_WIDGET_REALIZED (sheet)) - return; - - gdk_drawable_get_size (sheet->sheet_window, NULL, &height); - - if (sheet->column_titles_visible) - { - y = sheet->column_title_area.height; - } - - if (sheet->row_title_area.height != height || sheet->row_title_area.y != y) - { - sheet->row_title_area.y = y; - sheet->row_title_area.height = height; - gdk_window_move_resize (sheet->row_title_window, - sheet->row_title_area.x, - sheet->row_title_area.y, - sheet->row_title_area.width, - sheet->row_title_area.height); - } - - 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, - sheet->row_title_area.height); - - if (!GTK_WIDGET_DRAWABLE (sheet)) return; - - draw_row_title_buttons_range (sheet, min_visible_row (sheet), - max_visible_row (sheet)); -} - - -static void -psppire_sheet_size_allocate_entry (PsppireSheet *sheet) -{ - GtkAllocation entry_alloc; - PsppireSheetCellAttr attributes = { 0 }; - GtkEntry *sheet_entry; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return; - - sheet_entry = psppire_sheet_get_entry (sheet); - - if ( ! psppire_sheet_get_attributes (sheet, sheet->active_cell.row, - sheet->active_cell.col, - &attributes) ) - return ; - - if ( GTK_WIDGET_REALIZED (sheet->entry_widget) ) - { - GtkStyle *style = GTK_WIDGET (sheet_entry)->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; - } - - rectangle_from_cell (sheet, sheet->active_cell.row, - sheet->active_cell.col, &entry_alloc); - - entry_alloc.x += sheet->cell_padding->left; - entry_alloc.y += sheet->cell_padding->right; - entry_alloc.width -= sheet->cell_padding->left + sheet->cell_padding->right; - entry_alloc.height -= sheet->cell_padding->top + sheet->cell_padding->bottom; - - - 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 -set_entry_widget_font (PsppireSheet *sheet) -{ - GtkRcStyle *style = gtk_widget_get_modifier_style (sheet->entry_widget); - - pango_font_description_free (style->font_desc); - style->font_desc = pango_font_description_copy (GTK_WIDGET (sheet)->style->font_desc); - - gtk_widget_modify_style (sheet->entry_widget, style); -} - -static void -create_sheet_entry (PsppireSheet *sheet) -{ - if (sheet->entry_widget) - { - gtk_widget_unparent (sheet->entry_widget); - } - - sheet->entry_widget = g_object_new (sheet->entry_type, NULL); - g_object_ref_sink (sheet->entry_widget); - - gtk_widget_size_request (sheet->entry_widget, NULL); - - if ( GTK_IS_ENTRY (sheet->entry_widget)) - { - g_object_set (sheet->entry_widget, - "has-frame", FALSE, - NULL); - } - - if (GTK_WIDGET_REALIZED (sheet)) - { - gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window); - gtk_widget_set_parent (sheet->entry_widget, GTK_WIDGET (sheet)); - gtk_widget_realize (sheet->entry_widget); - } - - g_signal_connect_swapped (sheet->entry_widget, "key_press_event", - G_CALLBACK (psppire_sheet_entry_key_press), - sheet); - - set_entry_widget_font (sheet); - - gtk_widget_show (sheet->entry_widget); -} - - -/* Finds the last child widget that happens to be of type GtkEntry */ -static void -find_entry (GtkWidget *w, gpointer user_data) -{ - GtkWidget **entry = user_data; - if ( GTK_IS_ENTRY (w)) - { - *entry = w; - } -} - - -GtkEntry * -psppire_sheet_get_entry (PsppireSheet *sheet) -{ - GtkWidget *w = sheet->entry_widget; - - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), NULL); - g_return_val_if_fail (sheet->entry_widget != NULL, NULL); - - while (! GTK_IS_ENTRY (w)) - { - GtkWidget *entry = NULL; - - if (GTK_IS_CONTAINER (w)) - { - gtk_container_forall (GTK_CONTAINER (w), find_entry, &entry); - - if (NULL == entry) - break; - - w = entry; - } - } - - return GTK_ENTRY (w); -} - - -static void -draw_button (PsppireSheet *sheet, GdkWindow *window, - PsppireSheetButton *button, gboolean is_sensitive, - GdkRectangle allocation) -{ - GtkShadowType shadow_type; - gint text_width = 0, text_height = 0; - PangoAlignment align = PANGO_ALIGN_LEFT; - - gboolean rtl ; - - gint state = 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, - allocation.x, allocation.y, - allocation.width, allocation.height); - - gtk_widget_ensure_style (sheet->button); - - gtk_paint_box (sheet->button->style, window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - &allocation, - GTK_WIDGET (sheet->button), - NULL, - allocation.x, allocation.y, - allocation.width, allocation.height); - - state = button->state; - if (!is_sensitive) state = GTK_STATE_INSENSITIVE; - - if (state == GTK_STATE_ACTIVE) - shadow_type = GTK_SHADOW_IN; - else - shadow_type = GTK_SHADOW_OUT; - - if (state != GTK_STATE_NORMAL && state != GTK_STATE_INSENSITIVE) - gtk_paint_box (sheet->button->style, window, - button->state, shadow_type, - &allocation, GTK_WIDGET (sheet->button), - NULL, - allocation.x, allocation.y, - allocation.width, allocation.height); - - if ( button->overstruck) - { - GdkPoint points[2] = { - {allocation.x, allocation.y}, - {allocation.x + allocation.width, - allocation.y + allocation.height} - }; - - gtk_paint_polygon (sheet->button->style, - window, - button->state, - shadow_type, - NULL, - GTK_WIDGET (sheet), - NULL, - points, - 2, - TRUE); - } - - if (button->label_visible) - { - 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); - - allocation.y += 2 * sheet->button->style->ythickness; - - if (button->label && strlen (button->label) > 0) - { - PangoRectangle rect; - gchar *line = button->label; - - PangoLayout *layout = NULL; - gint real_x = allocation.x; - gint real_y = allocation.y; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), line); - pango_layout_get_extents (layout, NULL, &rect); - - text_width = PANGO_PIXELS (rect.width); - switch (button->justification) - { - 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); - } - 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], - NULL); - gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->white_gc, NULL); - - } - - psppire_sheet_button_free (button); -} - - -/* Draw the column title buttons FIRST through to LAST */ -static void -draw_column_title_buttons_range (PsppireSheet *sheet, gint first, gint last) -{ - GdkRectangle rect; - gint col; - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - - if (!sheet->column_titles_visible) return; - - g_return_if_fail (first >= min_visible_column (sheet)); - g_return_if_fail (last <= max_visible_column (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); - - rect.x -= sheet->hadjustment->value; - - minimize_int (&rect.width, sheet->column_title_area.width); - maximize_int (&rect.x, 0); - - gdk_window_begin_paint_rect (sheet->column_title_window, &rect); - - for (col = first ; col <= last ; ++col) - { - GdkRectangle allocation; - gboolean is_sensitive = FALSE; - - PsppireSheetButton * - button = psppire_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 = psppire_sheet_model_get_column_sensitivity (sheet->model, col); - - draw_button (sheet, sheet->column_title_window, - button, is_sensitive, allocation); - } - - gdk_window_end_paint (sheet->column_title_window); -} - - -static void -draw_row_title_buttons_range (PsppireSheet *sheet, gint first, gint last) -{ - GdkRectangle rect; - gint row; - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - - if (!sheet->row_titles_visible) return; - - g_return_if_fail (first >= min_visible_row (sheet)); - g_return_if_fail (last <= max_visible_row (sheet)); - - 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); - - rect.y -= sheet->vadjustment->value; - - minimize_int (&rect.height, sheet->row_title_area.height); - maximize_int (&rect.y, 0); - - gdk_window_begin_paint_rect (sheet->row_title_window, &rect); - for (row = first; row <= last; ++row) - { - GdkRectangle allocation; - - gboolean is_sensitive = FALSE; - - PsppireSheetButton *button = - psppire_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; - - allocation.width = sheet->row_title_area.width; - allocation.height = psppire_axis_unit_size (sheet->vaxis, row); - is_sensitive = psppire_sheet_model_get_row_sensitivity (sheet->model, row); - - draw_button (sheet, sheet->row_title_window, - button, is_sensitive, allocation); - } - - gdk_window_end_paint (sheet->row_title_window); -} - -/* SCROLLBARS - * - * functions: - * adjust_scrollbars - * vadjustment_value_changed - * hadjustment_value_changed */ - - -static void -update_adjustment (GtkAdjustment *adj, PsppireAxis *axis, gint page_size) -{ - double position = - (adj->value + adj->page_size) - / - (adj->upper - adj->lower); - - const glong last_item = psppire_axis_unit_count (axis) - 1; - - if (isnan (position) || position < 0) - position = 0; - - adj->upper = - psppire_axis_start_pixel (axis, last_item) - + - psppire_axis_unit_size (axis, last_item) - ; - - adj->lower = 0; - adj->page_size = page_size; - -#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); -} - - -static void -adjust_scrollbars (PsppireSheet *sheet) -{ - gint width, height; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - gdk_drawable_get_size (sheet->sheet_window, &width, &height); - - if ( sheet->row_titles_visible) - width -= sheet->row_title_area.width; - - 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->vadjustment->step_increment = - ROWS_PER_STEP * - psppire_axis_unit_size (sheet->vaxis, last_row); - - 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 (sheet->hadjustment) - { - gint last_col = psppire_axis_unit_count (sheet->haxis) - 1; - sheet->hadjustment->step_increment = 1; - - sheet->hadjustment->page_increment = width; - - 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); - } -} - -/* Subtracts the region of WIDGET from REGION */ -static void -subtract_widget_region (GdkRegion *region, GtkWidget *widget) -{ - GdkRectangle rect; - GdkRectangle intersect; - GdkRegion *region2; - - gdk_region_get_clipbox (region, &rect); - gtk_widget_intersect (widget, - &rect, - &intersect); - - region2 = gdk_region_rectangle (&intersect); - gdk_region_subtract (region, region2); - gdk_region_destroy (region2); -} - -static void -vadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data) -{ - GdkRegion *region; - PsppireSheet *sheet = PSPPIRE_SHEET (data); - - g_return_if_fail (adjustment != NULL); - - if ( ! GTK_WIDGET_REALIZED (sheet)) return; - - gtk_widget_hide (sheet->entry_widget); - - region = - gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window)); - - subtract_widget_region (region, sheet->button); - gdk_window_begin_paint_region (sheet->sheet_window, region); - - draw_sheet_region (sheet, region); - - draw_row_title_buttons (sheet); - psppire_sheet_draw_active_cell (sheet); - - gdk_window_end_paint (sheet->sheet_window); - gdk_region_destroy (region); -} - - -static void -hadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data) -{ - GdkRegion *region; - PsppireSheet *sheet = PSPPIRE_SHEET (data); - - g_return_if_fail (adjustment != NULL); - - if ( ! GTK_WIDGET_REALIZED (sheet)) return; - - gtk_widget_hide (sheet->entry_widget); - - - region = - gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window)); - - subtract_widget_region (region, sheet->button); - gdk_window_begin_paint_region (sheet->sheet_window, region); - - draw_sheet_region (sheet, region); - - draw_column_title_buttons (sheet); - - psppire_sheet_draw_active_cell (sheet); - - gdk_window_end_paint (sheet->sheet_window); - - gdk_region_destroy (region); -} - - -/* COLUMN RESIZING */ -static void -draw_xor_vline (PsppireSheet *sheet) -{ - gint height; - gint xpos = sheet->x_drag; - gdk_drawable_get_size (sheet->sheet_window, - NULL, &height); - - if (sheet->row_titles_visible) - xpos += sheet->row_title_area.width; - - gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc, - xpos, - sheet->column_title_area.height, - xpos, - height + CELL_SPACING); -} - -/* ROW RESIZING */ -static void -draw_xor_hline (PsppireSheet *sheet) - -{ - gint width; - gint ypos = sheet->y_drag; - - gdk_drawable_get_size (sheet->sheet_window, - &width, NULL); - - - 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 -draw_xor_rectangle (PsppireSheet *sheet, PsppireSheetRange range) -{ - gint i = 0; - GdkRectangle clip_area, area; - GdkGCValues values; - - 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); - - clip_area.x = sheet->row_title_area.width; - clip_area.y = sheet->column_title_area.height; - - gdk_drawable_get_size (sheet->sheet_window, - &clip_area.width, &clip_area.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); - - 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); -} - - -static void -set_column_width (PsppireSheet *sheet, - gint column, - gint width) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis)) - return; - - if ( width <= 0) - return; - - psppire_axis_resize (sheet->haxis, column, - width - sheet->cell_padding->left - - sheet->cell_padding->right); - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - draw_column_title_buttons (sheet); - adjust_scrollbars (sheet); - psppire_sheet_size_allocate_entry (sheet); - redraw_range (sheet, NULL); - } -} - -static void -set_row_height (PsppireSheet *sheet, - gint row, - gint height) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (PSPPIRE_IS_SHEET (sheet)); - - if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis)) - return; - - if (height <= 0) - return; - - psppire_axis_resize (sheet->vaxis, row, - height - sheet->cell_padding->top - - sheet->cell_padding->bottom); - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) ) - { - draw_row_title_buttons (sheet); - adjust_scrollbars (sheet); - psppire_sheet_size_allocate_entry (sheet); - redraw_range (sheet, NULL); - } -} - -static gboolean -psppire_sheet_get_attributes (const PsppireSheet *sheet, gint row, gint col, - PsppireSheetCellAttr *attr) -{ - GdkColor *fg, *bg; - const GtkJustification *j ; - GdkColormap *colormap; - - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), FALSE); - - if (row < 0 || col < 0) return FALSE; - - attr->foreground = GTK_WIDGET (sheet)->style->black; - attr->background = sheet->color[BG_COLOR]; - - 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; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (sheet)); - fg = psppire_sheet_model_get_foreground (sheet->model, row, col); - if ( fg ) - { - gdk_colormap_alloc_color (colormap, fg, TRUE, TRUE); - attr->foreground = *fg; - } - - bg = psppire_sheet_model_get_background (sheet->model, row, col); - if ( bg ) - { - gdk_colormap_alloc_color (colormap, bg, TRUE, TRUE); - attr->background = *bg; - } - - attr->justification = - psppire_sheet_model_get_column_justification (sheet->model, col); - - j = psppire_sheet_model_get_justification (sheet->model, row, col); - if (j) - attr->justification = *j; - - return TRUE; -} - -static void -psppire_sheet_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (container); - - g_return_if_fail (callback != NULL); - - if (sheet->button && sheet->button->parent) - (* callback) (sheet->button, callback_data); - - if (sheet->entry_widget && GTK_IS_CONTAINER (sheet->entry_widget)) - (* callback) (sheet->entry_widget, callback_data); -} - - -PsppireSheetModel * -psppire_sheet_get_model (const PsppireSheet *sheet) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET (sheet), NULL); - - return sheet->model; -} - - -PsppireSheetButton * -psppire_sheet_button_new (void) -{ - PsppireSheetButton *button = g_malloc (sizeof (PsppireSheetButton)); - - button->state = GTK_STATE_NORMAL; - button->label = NULL; - button->label_visible = TRUE; - button->justification = GTK_JUSTIFY_FILL; - button->overstruck = FALSE; - - return button; -} - - -void -psppire_sheet_button_free (PsppireSheetButton *button) -{ - if (!button) return ; - - g_free (button->label); - g_free (button); -} - -static void -append_cell_text (GString *string, const PsppireSheet *sheet, gint r, gint c) -{ - gchar *celltext = psppire_sheet_cell_get_text (sheet, r, c); - - if ( NULL == celltext) - return; - - g_string_append (string, celltext); - g_free (celltext); -} - - -static GString * -range_to_text (const PsppireSheet *sheet) -{ - gint r, c; - GString *string; - - if ( !psppire_sheet_range_isvisible (sheet, &sheet->range)) - return NULL; - - string = g_string_sized_new (80); - - for (r = sheet->range.row0; r <= sheet->range.rowi; ++r) - { - for (c = sheet->range.col0; c < sheet->range.coli; ++c) - { - append_cell_text (string, sheet, r, c); - g_string_append (string, "\t"); - } - append_cell_text (string, sheet, r, c); - if ( r < sheet->range.rowi) - g_string_append (string, "\n"); - } - - return string; -} - -static GString * -range_to_html (const PsppireSheet *sheet) -{ - gint r, c; - GString *string; - - if ( !psppire_sheet_range_isvisible (sheet, &sheet->range)) - return NULL; - - string = g_string_sized_new (480); - - g_string_append (string, "\n"); - g_string_append (string, "\n"); - g_string_append (string, "\n"); - for (r = sheet->range.row0; r <= sheet->range.rowi; ++r) - { - g_string_append (string, "\n"); - for (c = sheet->range.col0; c <= sheet->range.coli; ++c) - { - g_string_append (string, "\n"); - } - g_string_append (string, "\n"); - } - g_string_append (string, "
"); - append_cell_text (string, sheet, r, c); - g_string_append (string, "
\n"); - g_string_append (string, "\n"); - g_string_append (string, "\n"); - - return string; -} - -enum { - SELECT_FMT_NULL, - SELECT_FMT_TEXT, - SELECT_FMT_HTML -}; - -static void -primary_get_cb (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - guint info, - gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - GString *string = NULL; - - switch (info) - { - case SELECT_FMT_TEXT: - string = range_to_text (sheet); - break; - case SELECT_FMT_HTML: - string = range_to_html (sheet); - break; - default: - g_assert_not_reached (); - } - - gtk_selection_data_set (selection_data, selection_data->target, - 8, - (const guchar *) string->str, string->len); - g_string_free (string, TRUE); -} - -static void -primary_clear_cb (GtkClipboard *clipboard, - gpointer data) -{ - PsppireSheet *sheet = PSPPIRE_SHEET (data); - if ( ! GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - return; - - psppire_sheet_unselect_range (sheet); -} - -static void -psppire_sheet_update_primary_selection (PsppireSheet *sheet) -{ - static const GtkTargetEntry targets[] = { - { "UTF8_STRING", 0, SELECT_FMT_TEXT }, - { "STRING", 0, SELECT_FMT_TEXT }, - { "TEXT", 0, SELECT_FMT_TEXT }, - { "COMPOUND_TEXT", 0, SELECT_FMT_TEXT }, - { "text/plain;charset=utf-8", 0, SELECT_FMT_TEXT }, - { "text/plain", 0, SELECT_FMT_TEXT }, - { "text/html", 0, SELECT_FMT_HTML } - }; - - GtkClipboard *clipboard; - - if (!GTK_WIDGET_REALIZED (sheet)) - return; - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (sheet), - GDK_SELECTION_PRIMARY); - - if (psppire_sheet_range_isvisible (sheet, &sheet->range)) - { - if (!gtk_clipboard_set_with_owner (clipboard, targets, - G_N_ELEMENTS (targets), - primary_get_cb, primary_clear_cb, - G_OBJECT (sheet))) - primary_clear_cb (clipboard, sheet); - } - else - { - if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (sheet)) - gtk_clipboard_clear (clipboard); - } -} diff --git a/lib/gtk-contrib/psppire-sheet.h b/lib/gtk-contrib/psppire-sheet.h deleted file mode 100644 index eccffe84c0..0000000000 --- a/lib/gtk-contrib/psppire-sheet.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - Copyright (C) 2006, 2008 Free Software Foundation - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - - This file is derived from the gtksheet.c and extensively modified for the - requirements of PSPPIRE. The changes are copyright by the - Free Software Foundation. The copyright notice for the original work is - below. - - - GtkSheet widget for Gtk+. - * Copyright (C) 1999-2001 Adrian E. Feiguin - * - * Based on GtkClist widget by Jay Painter, but major changes. - * Memory allocation routines inspired on SC (Spreadsheet Calculator) - * - * 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 __PSPPIRE_SHEET_H__ -#define __PSPPIRE_SHEET_H__ - -#include - -#include "gtkextra-sheet.h" -#include -#include - -G_BEGIN_DECLS - -/* sheet->select_status */ -enum -{ - PSPPIRE_SHEET_NORMAL, - PSPPIRE_SHEET_ROW_SELECTED, - PSPPIRE_SHEET_COLUMN_SELECTED, - PSPPIRE_SHEET_RANGE_SELECTED -}; - - -#define PSPPIRE_TYPE_SHEET_RANGE (psppire_sheet_range_get_type ()) -#define PSPPIRE_TYPE_SHEET_CELL (psppire_sheet_cell_get_type ()) - - -#define PSPPIRE_TYPE_SHEET (psppire_sheet_get_type ()) -#define PSPPIRE_SHEET(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_TYPE_SHEET, PsppireSheet) -#define PSPPIRE_SHEET_CLASS(klass) G_TYPE_CHECK_CLASS_CAST ((klass), PSPPIRE_TYPE_SHEET, PsppireSheetClass) -#define PSPPIRE_IS_SHEET(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_SHEET) - - -typedef struct _PsppireSheetClass PsppireSheetClass; -typedef struct _PsppireSheetCellAttr PsppireSheetCellAttr; - -typedef struct _PsppireSheetHoverTitle PsppireSheetHoverTitle; - - -struct _PsppireSheetCellAttr -{ - GtkJustification justification; - GdkColor foreground; - GdkColor background; - PsppireSheetCellBorder border; -}; - -struct _PsppireSheetHoverTitle -{ - GtkWidget *window; - GtkWidget *label; - gint row, column; -}; - -enum - { - BG_COLOR, - GRID_COLOR, - n_COLORS - }; - -struct _PsppireSheet -{ - GtkBin parent; - - gboolean dispose_has_run; - PsppireAxis *haxis; - PsppireAxis *vaxis; - - guint16 flags; - - PsppireSheetModel *model; - - /* Component colors */ - GdkColor color[n_COLORS]; - gboolean show_grid; - - /* active cell */ - PsppireSheetCell active_cell; - - /* The GtkEntry used for editing the cells */ - GtkWidget *entry_widget; - - /* The type of entry_widget */ - GType entry_type; - - /* global selection button */ - GtkWidget *button; - - /* sheet state */ - gint select_status; - - /* selected range */ - PsppireSheetRange range; - - /* The space between a cell's contents and its border */ - GtkBorder *cell_padding; - - /* the scrolling window and its height and width to - * make things a little speedier */ - GdkWindow *sheet_window; - - /* border shadow style */ - GtkShadowType shadow_type; - - /* Column Titles */ - 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; - - /* xor GC for the verticle drag line */ - GdkGC *xor_gc; - - /* gc for drawing unselected cells */ - GdkGC *fg_gc; - GdkGC *bg_gc; - - /* cursor used to indicate dragging */ - GdkCursor *cursor_drag; - - /* the current x-pixel location of the xor-drag vline */ - gint x_drag; - - /* the current y-pixel location of the xor-drag hline */ - gint y_drag; - - /* current cell being dragged */ - PsppireSheetCell drag_cell; - /* current range being dragged */ - PsppireSheetRange drag_range; - - /* Used for the subtitle (popups) */ - gint motion_timer; - PsppireSheetHoverTitle *hover_window; - - gulong update_handler_id; -}; - -struct _PsppireSheetClass -{ - GtkBinClass parent_class; - - gboolean (*set_scroll_adjustments) (PsppireSheet *sheet, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment); - - void (*select_row) (PsppireSheet *sheet, gint row); - - void (*select_column) (PsppireSheet *sheet, gint column); - - void (*select_range) (PsppireSheet *sheet, PsppireSheetRange *range); - - void (*resize_range) (PsppireSheet *sheet, - PsppireSheetRange *old_range, - PsppireSheetRange *new_range); - - void (*move_range) (PsppireSheet *sheet, - PsppireSheetRange *old_range, - PsppireSheetRange *new_range); - - gboolean (*traverse) (PsppireSheet *sheet, - gint row, gint column, - gint *new_row, gint *new_column); - - gboolean (*activate) (PsppireSheet *sheet, - gint row, gint column); - - void (*changed) (PsppireSheet *sheet, - gint row, gint column); -}; - -GType psppire_sheet_get_type (void); -GType psppire_sheet_range_get_type (void); - - -/* create a new sheet */ -GtkWidget * psppire_sheet_new (PsppireSheetModel *model); - -/* create a new sheet with custom entry */ -GtkWidget * -psppire_sheet_new_with_custom_entry (GType entry_type); - -/* Change entry */ -void psppire_sheet_change_entry (PsppireSheet *sheet, GType entry_type); - -GtkEntry *psppire_sheet_get_entry (PsppireSheet *sheet); - - -void psppire_sheet_get_selected_range (PsppireSheet *sheet, - PsppireSheetRange *range); - -void psppire_sheet_show_grid (PsppireSheet *sheet, - gboolean show); - -gboolean psppire_sheet_grid_visible (PsppireSheet *sheet); - - -/* scroll the viewing area of the sheet to the given column - * and row; row_align and col_align are between 0-1 representing the - * 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 psppire_sheet_moveto (PsppireSheet *sheet, - gint row, - gint column, - gfloat row_align, - gfloat col_align); - - -void psppire_sheet_show_row_titles (PsppireSheet *sheet); -void psppire_sheet_hide_row_titles (PsppireSheet *sheet); -void psppire_sheet_show_column_titles (PsppireSheet *sheet); -void psppire_sheet_hide_column_titles (PsppireSheet *sheet); - -/* select the row. The range is then highlighted, and the bounds are stored - * in sheet->range */ -void psppire_sheet_select_row (PsppireSheet * sheet, gint row); - -/* select the column. The range is then highlighted, and the bounds are stored - * in sheet->range */ -void psppire_sheet_select_column (PsppireSheet * sheet, gint column); - -/* highlight the selected range and store bounds in sheet->range */ -void psppire_sheet_select_range (PsppireSheet *sheet, const PsppireSheetRange *range); - -void psppire_sheet_get_visible_range (PsppireSheet *sheet, PsppireSheetRange *range); - - -/* obvious */ -void psppire_sheet_unselect_range (PsppireSheet *sheet); - -/* set active cell where the entry will be displayed */ -void psppire_sheet_set_active_cell (PsppireSheet *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 psppire_sheet_get_active_cell (PsppireSheet *sheet, - gint *row, gint *column); - -/* get cell contents */ -gchar *psppire_sheet_cell_get_text (const PsppireSheet *sheet, gint row, gint col); - - -void psppire_sheet_set_model (PsppireSheet *sheet, - PsppireSheetModel *model); - -PsppireSheetModel * psppire_sheet_get_model (const PsppireSheet *sheet); - - -G_END_DECLS - - -#endif /* __PSPPIRE_SHEET_H__ */ - - diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 2b01346bd8..b852ceabde 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -1,7 +1,5 @@ ## Process this file with automake to produce Makefile.in -*- makefile -*- -include $(top_srcdir)/src/ui/gui/sheet/automake.mk - UI_FILES = \ src/ui/gui/aggregate.ui \ src/ui/gui/autorecode.ui \ @@ -71,8 +69,7 @@ endif src_ui_gui_psppire_LDADD = \ - src/ui/gui/sheet/libsheet.la \ - lib/gtk-contrib/libgtksheet.a \ + lib/gtk-contrib/libxpaned.a \ src/ui/libuicommon.la \ src/libpspp.la \ src/libpspp-core.la \ diff --git a/src/ui/gui/sheet/automake.mk b/src/ui/gui/sheet/automake.mk deleted file mode 100644 index 1043a5736b..0000000000 --- a/src/ui/gui/sheet/automake.mk +++ /dev/null @@ -1,13 +0,0 @@ -## Process this file with automake to produce Makefile.in -*- makefile -*- - -if HAVE_GUI -noinst_LTLIBRARIES += src/ui/gui/sheet/libsheet.la - -src_ui_gui_sheet_libsheet_la_CFLAGS = $(GTK_CFLAGS) - -src_ui_gui_sheet_libsheet_la_SOURCES = \ - src/ui/gui/sheet/psppire-axis.c \ - src/ui/gui/sheet/psppire-axis.h \ - src/ui/gui/sheet/psppire-sheetmodel.c \ - src/ui/gui/sheet/psppire-sheetmodel.h -endif diff --git a/src/ui/gui/sheet/psppire-axis.c b/src/ui/gui/sheet/psppire-axis.c deleted file mode 100644 index 9cc879dc12..0000000000 --- a/src/ui/gui/sheet/psppire-axis.c +++ /dev/null @@ -1,634 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2008, 2009, 2010 Free Software Foundation - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include -#include -#include - -#include -#include -#include -#include "psppire-axis.h" -#include -#include - - -/* Signals */ -enum - { - RESIZE_UNIT, - n_signals - }; - -static guint signals[n_signals] ; - -/* --- 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; - - -struct axis_node -{ - struct tower_node pixel_node; - struct tower_node unit_node; -}; - -void -psppire_axis_dump (const PsppireAxis *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 / (gdouble) n->size); - - n = tower_next (&a->unit_tower, n); - } - g_debug ("\n"); -} - -/* Increment the size of every unit by INC. - Note that INC is signed. So if INC is negative, - then size will end up smaller. -*/ -static void -axis_increment (PsppireAxis *axis, gint inc) -{ - struct tower_node *n = tower_first (&axis->pixel_tower); - - while (n) - { - struct axis_node *an = tower_data (n, struct axis_node, pixel_node); - struct tower_node *pn = &an->pixel_node; - const gint existing_size = tower_node_get_size (pn); - - tower_resize (&axis->pixel_tower, pn, existing_size + inc * - tower_node_get_size (&an->unit_node)); - - n = tower_next (&axis->pixel_tower, n); - } -} - - -/* Return the unit covered by PIXEL */ -gint -psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel) -{ - unsigned long int start; - struct tower_node *n; - struct axis_node *an; - gdouble fraction; - - glong size = tower_height (&a->pixel_tower); - - g_return_val_if_fail (pixel >= 0, -1); - - if (pixel >= size) - { - gint n_items = tower_height (&a->unit_tower); - glong extra = pixel - size; - - return n_items - 1 + DIV_RND_UP (extra, a->default_size); - } - - - n = tower_lookup (&a->pixel_tower, pixel, &start); - an = tower_data (n, struct axis_node, pixel_node); - - fraction = (pixel - start) / (gdouble) tower_node_get_size (&an->pixel_node); - - return tower_node_get_level (&an->unit_node) - + fraction * tower_node_get_size (&an->unit_node); -} - - -gint -psppire_axis_unit_count (const PsppireAxis *a) -{ - glong filler = 0; - glong actual_size; - - actual_size = tower_height (&a->pixel_tower); - - if ( actual_size < a->min_extent ) - filler = DIV_RND_UP (a->min_extent - actual_size, a->default_size); - - return tower_height (&a->unit_tower) + filler; -} - - -/* Return the starting pixel of UNIT */ -glong -psppire_axis_start_pixel (const PsppireAxis *a, gint unit) -{ - gdouble fraction; - struct tower_node *n ; - struct axis_node *an; - - unsigned long int start; - - gint the_count, size ; - - the_count = tower_height (&a->unit_tower); - size = tower_height (&a->pixel_tower); - - if ( unit >= the_count) - { - return size + (unit - the_count) * a->default_size; - } - - if ( unit < 0) - return -1; - - if ( unit >= tower_height (&a->unit_tower)) - return -1; - - n = tower_lookup (&a->unit_tower, unit, &start); - - an = tower_data (n, struct axis_node, unit_node); - - fraction = (unit - start) / (gdouble) tower_node_get_size (&an->unit_node); - - return tower_node_get_level (&an->pixel_node) + - rint (fraction * tower_node_get_size (&an->pixel_node)); -} - -gint -psppire_axis_unit_size (const PsppireAxis *axis, gint unit) -{ - struct tower_node *n ; - struct axis_node *an; - - unsigned long int start; - - if (unit >= tower_height (&axis->unit_tower)) - return axis->default_size; - - if ( unit < 0) - return 0; - - if ( unit >= tower_height (&axis->unit_tower)) - return 0; - - n = tower_lookup (&axis->unit_tower, unit, &start); - - an = tower_data (n, struct axis_node, unit_node); - - return rint (tower_node_get_size (&an->pixel_node) - / (gdouble) tower_node_get_size (&an->unit_node)); -} - - - -/* --- functions --- */ -/** - * psppire_axis_get_type: - * @returns: the type ID for accelerator groups. - */ -GType -psppire_axis_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = { - sizeof (PsppireAxisClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) psppire_axis_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireAxis), - 0, /* n_preallocs */ - (GInstanceInitFunc) psppire_axis_init, - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, - "PsppireAxis", - &object_info, 0); - - } - - return object_type; -} - -enum - { - PROP_0, - PROP_MIN_EXTENT, - PROP_DEFAULT_SIZE, - PROP_PADDING - }; - - -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_PADDING: - g_value_set_int (value, axis->padding); - break; - 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_PADDING: - { - const gint old_value = axis->padding; - axis->padding = g_value_get_int (value); - axis_increment (axis, axis->padding - old_value); - } - break; - 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 *padding_spec; - GParamSpec *min_extent_spec; - GParamSpec *default_size_spec; - - parent_class = g_type_class_peek_parent (class); - - 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); - - padding_spec = - g_param_spec_int ("padding", - "Padding", - "Extra space implicitly added to each unit", - 0, G_MAXINT, - 0, - G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE ); - - - g_object_class_install_property (object_class, - PROP_PADDING, - padding_spec); - - - - 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 - ); - - - object_class->finalize = psppire_axis_finalize; -} - - -static void -psppire_axis_init (PsppireAxis *axis) -{ - tower_init (&axis->pixel_tower); - tower_init (&axis->unit_tower); - - axis->pool = pool_create (); - axis->padding = 0; -} - - -static void -psppire_axis_finalize (GObject *object) -{ - PsppireAxis *a = PSPPIRE_AXIS (object); - pool_destroy (a->pool); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -/** - * psppire_axis_new: - * @returns: a new #PsppireAxis object - * - * Creates a new #PsppireAxis. - */ -PsppireAxis* -psppire_axis_new (void) -{ - return g_object_new (G_TYPE_PSPPIRE_AXIS, NULL); -} - - - - -void -psppire_axis_append (PsppireAxis *a, gint size) -{ - psppire_axis_append_n (a, 1, size); -} - - -/* Append N_UNITS of size SIZE to A. - The value of the "padding" property will be added to SIZE - unit before appending. -*/ -void -psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size) -{ - struct axis_node *node; - - if (n_units == 0) - return; - - node = pool_malloc (a->pool, sizeof *node); - - tower_insert (&a->unit_tower, n_units, &node->unit_node, NULL); - tower_insert (&a->pixel_tower, (size + a->padding) * n_units, - &node->pixel_node, NULL); -} - - -/* Split the node of both towers at POSN */ -static void -split (PsppireAxis *a, gint posn) -{ - unsigned long int existing_unit_size; - unsigned long int existing_pixel_size; - unsigned long int start; - gdouble 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) / (gdouble) 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, - rintf (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, - rintf (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. - The value of the "padding" property will be added to SIZE before - the unit is inserted. - */ -void -psppire_axis_insert (PsppireAxis *a, gint posn, gint size) -{ - struct axis_node *before = NULL; - struct axis_node *new_node; - - g_return_if_fail ( posn >= 0); - g_return_if_fail ( posn <= tower_height (&a->unit_tower)); - - if ( posn < tower_height (&a->unit_tower)) - { - unsigned long int start = 0; - struct tower_node *n; - - split (a, posn); - - n = tower_lookup (&a->unit_tower, posn, &start); - g_assert (posn == start); - - before = tower_data (n, struct axis_node, unit_node); - } - - new_node = pool_malloc (a->pool, sizeof (*new_node)); - - tower_insert (&a->unit_tower, - 1, - &new_node->unit_node, - before ? &before->unit_node : NULL); - - tower_insert (&a->pixel_tower, - size + a->padding, - &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 (PsppireAxis *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); -} - - -/* - Set the size of the unit at POSN to be SIZE plus the - current value of "padding" - */ -void -psppire_axis_resize (PsppireAxis *axis, gint posn, glong size) -{ - 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 (&axis->unit_tower)) - return ; - - an = make_single (axis, posn); - - tower_resize (&axis->pixel_tower, &an->pixel_node, size + axis->padding); - - g_signal_emit (axis, signals[RESIZE_UNIT], 0, posn, size + axis->padding); -} - - - - - - -void -psppire_axis_clear (PsppireAxis *a) -{ - pool_destroy (a->pool); - a->pool = pool_create (); - - tower_init (&a->pixel_tower); - tower_init (&a->unit_tower); -} - - - -void -psppire_axis_delete (PsppireAxis *a, gint first, gint n_units) -{ - gint units_to_delete = n_units; - unsigned long int start; - struct tower_node *unit_node ; - g_return_if_fail (first + n_units <= tower_height (&a->unit_tower)); - - split (a, first); - split (a, first + n_units); - - unit_node = tower_lookup (&a->unit_tower, first, &start); - g_assert (start == first); - - while (units_to_delete > 0) - { - struct tower_node *next_unit_node; - struct axis_node *an = tower_data (unit_node, - struct axis_node, unit_node); - - g_assert (unit_node == &an->unit_node); - g_assert (unit_node->size <= n_units); - - units_to_delete -= unit_node->size; - - next_unit_node = tower_next (&a->unit_tower, unit_node); - - tower_delete (&a->unit_tower, unit_node); - tower_delete (&a->pixel_tower, &an->pixel_node); - - pool_free (a->pool, an); - - unit_node = next_unit_node; - } -} diff --git a/src/ui/gui/sheet/psppire-axis.h b/src/ui/gui/sheet/psppire-axis.h deleted file mode 100644 index 50a6a39dc2..0000000000 --- a/src/ui/gui/sheet/psppire-axis.h +++ /dev/null @@ -1,92 +0,0 @@ -/* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2008, 2009 Free Software Foundation - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -#ifndef PSPPIRE_AXIS_H__ -#define PSPPIRE_AXIS_H__ - - -#include -#include -#include - -G_BEGIN_DECLS - - -/* --- type macros --- */ -#define G_TYPE_PSPPIRE_AXIS (psppire_axis_get_type ()) -#define PSPPIRE_AXIS(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS, PsppireAxis)) -#define PSPPIRE_AXIS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass)) -#define PSPPIRE_IS_AXIS(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS)) -#define PSPPIRE_IS_AXIS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS)) -#define PSPPIRE_AXIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass)) - - - -/* --- typedefs & structures --- */ -typedef struct _PsppireAxis PsppireAxis; -typedef struct _PsppireAxisClass PsppireAxisClass; - -struct pool; - -struct _PsppireAxis -{ - GObject parent; - - struct tower pixel_tower; - struct tower unit_tower; - - struct pool *pool; - - glong min_extent; - gint default_size; - gint padding; -}; - -struct _PsppireAxisClass -{ - GObjectClass parent_class; -}; - -GType psppire_axis_get_type (void); - -PsppireAxis* psppire_axis_new (void); - - -/* Interface between axis and model */ - -void psppire_axis_insert (PsppireAxis *a, gint posn, gint size); - -void psppire_axis_append (PsppireAxis *a, gint size); - -void psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size); - -void psppire_axis_resize (PsppireAxis *a, gint posn, glong size); - -void psppire_axis_clear (PsppireAxis *); - -void psppire_axis_delete (PsppireAxis *, gint first, gint n_cases); - - - -gint psppire_axis_unit_count (const PsppireAxis *); -glong psppire_axis_start_pixel (const PsppireAxis *a, gint unit); -gint psppire_axis_unit_size (const PsppireAxis *a, gint unit); -gint psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel); - -G_END_DECLS - -#endif /* PSPPIRE_AXIS_H__ */ diff --git a/src/ui/gui/sheet/psppire-sheetmodel.c b/src/ui/gui/sheet/psppire-sheetmodel.c deleted file mode 100644 index a948d4535d..0000000000 --- a/src/ui/gui/sheet/psppire-sheetmodel.c +++ /dev/null @@ -1,548 +0,0 @@ -/* PsppireSheetModel --- an abstract model for the PsppireSheet widget. - Copyright (C) 2006, 2008 Free Software Foundation - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include -#include "psppire-sheetmodel.h" -#include - -enum { - RANGE_CHANGED, - ROWS_INSERTED, - ROWS_DELETED, - COLUMNS_INSERTED, - COLUMNS_DELETED, - LAST_SIGNAL -}; - -static guint sheet_model_signals[LAST_SIGNAL] = { 0 }; - - -static void psppire_sheet_model_base_init (gpointer g_class); - - -GType -psppire_sheet_model_get_type (void) -{ - static GType sheet_model_type = 0; - - if (! sheet_model_type) - { - static const GTypeInfo sheet_model_info = - { - sizeof (PsppireSheetModelIface), /* class_size */ - psppire_sheet_model_base_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - sheet_model_type = - g_type_register_static (G_TYPE_INTERFACE, "PsppireSheetModel", - &sheet_model_info, 0); - - g_type_interface_add_prerequisite (sheet_model_type, G_TYPE_OBJECT); - } - - return sheet_model_type; -} - -static void -psppire_sheet_model_base_init (gpointer g_class) -{ - static gboolean initialized = FALSE; - - if (! initialized) - { - sheet_model_signals[RANGE_CHANGED] = - g_signal_new ("range_changed", - PSPPIRE_TYPE_SHEET_MODEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PsppireSheetModelIface, range_changed), - NULL, NULL, - psppire_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - - - sheet_model_signals[ROWS_INSERTED] = - g_signal_new ("rows_inserted", - PSPPIRE_TYPE_SHEET_MODEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PsppireSheetModelIface, rows_inserted), - NULL, NULL, - psppire_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - - sheet_model_signals[ROWS_DELETED] = - g_signal_new ("rows_deleted", - PSPPIRE_TYPE_SHEET_MODEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PsppireSheetModelIface, rows_deleted), - NULL, NULL, - psppire_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - sheet_model_signals[COLUMNS_INSERTED] = - g_signal_new ("columns_inserted", - PSPPIRE_TYPE_SHEET_MODEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PsppireSheetModelIface, columns_inserted), - NULL, NULL, - psppire_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - - sheet_model_signals[COLUMNS_DELETED] = - g_signal_new ("columns_deleted", - PSPPIRE_TYPE_SHEET_MODEL, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PsppireSheetModelIface, columns_deleted), - NULL, NULL, - psppire_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - - - initialized = TRUE; - } -} - - -/** - * psppire_sheet_model_free_strings - * @sheet_model: A #PsppireSheetModel - * - * Returns: True if strings obtained with get_string should be freed by the - * sheet when no longer required. - **/ -gboolean -psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE); - - return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->free_strings; -} - - -/** - * psppire_sheet_model_get_string: - * @sheet_model: A #PsppireSheetModel - * @row: The row of the cell to be retrieved. - * @column: The column of the cell to be retrieved. - * - * Retrieves the datum at location ROW, COLUMN in the form of a string. - * Returns: The string representation of the datum, or NULL on error. - **/ -gchar * -psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), 0); - - g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string); - - return (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->get_string) (sheet_model, row, column); -} - -/** - * psppire_sheet_model_set_string - * @sheet_model: A #PsppireSheetModel - * @text: The text describing the datum to be set. - * @row: The row of the cell to be cleared. - * @column: The column of the cell to be cleared. - * - * Sets the datum at a location from a string. - * Returns: TRUE if the datum was changed, FALSE otherwise. - **/ -gboolean -psppire_sheet_model_set_string (PsppireSheetModel *sheet_model, - const gchar *text, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE); - - g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string); - - return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->set_string (sheet_model, - text, row, column); -} - - - -/** - * psppire_sheet_model_datum_clear: - * @sheet_model: A #PsppireSheetModel - * @row: The row of the cell to be cleared. - * @column: The column of the cell to be cleared. - * - * Called when the datum at a location is to be cleared. - * Returns: TRUE if the datum was cleared, FALSE otherwise. - **/ -gboolean -psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model), FALSE); - - g_assert (PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum); - - return PSPPIRE_SHEET_MODEL_GET_IFACE (sheet_model)->clear_datum (sheet_model, - row, column); -} - - -/** - * psppire_sheet_model_range_changed: - * @sheet_model: A #PsppireSheetModel - * @range: The #PsppireSheetRange range of cells which have changed. - * - * Emits the "range_changed" signal on @sheet_model. - **/ -void -psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model, - glong row0, glong col0, - glong rowi, glong coli) -{ - g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model)); - - g_signal_emit (sheet_model, sheet_model_signals[RANGE_CHANGED], 0, - row0, col0, rowi, coli); -} - - - - -/** - * psppire_sheet_model_rows_inserted: - * @sheet_model: A #PsppireSheetModel - * @row: The row before which the new rows should be inserted. - * @n_rows: The number of rows to insert. - * - * Emits the "rows_inserted" signal on @sheet_model. - **/ -void -psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model, - glong row, glong n_rows) -{ - g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model)); - - g_signal_emit (sheet_model, sheet_model_signals[ROWS_INSERTED], 0, - row, n_rows); -} - - -/** - * psppire_sheet_model_columns_inserted: - * @sheet_model: A #PsppireSheetModel - * @column: The column before which the new columns should be inserted. - * @n_columns: The number of columns to insert. - * - * Emits the "columns_inserted" signal on @sheet_model. - **/ -void -psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model, - glong column, glong n_columns) -{ - g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model)); - - g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_INSERTED], 0, - column, n_columns); -} - - - - -/** - * psppire_sheet_model_rows_deleted: - * @sheet_model: A #PsppireSheetModel - * @row: The first row to be deleted. - * @n_rows: The number of rows to delete. - * - * Emits the "rows_deleted" signal on @sheet_model. - **/ -void -psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model, - glong row, glong n_rows) -{ - g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model)); - - g_signal_emit (sheet_model, sheet_model_signals[ROWS_DELETED], 0, - row, n_rows); -} - - - -/** - * psppire_sheet_model_columns_deleted: - * @sheet_model: A #PsppireSheetModel - * @column: The first column to be deleted. - * @n_columns: The number of columns to delete. - * - * Emits the "columns_deleted" signal on @sheet_model. - **/ -void -psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model, - glong column, glong n_columns) -{ - g_return_if_fail (PSPPIRE_IS_SHEET_MODEL (sheet_model)); - - g_signal_emit (sheet_model, sheet_model_signals[COLUMNS_DELETED], 0, - column, n_columns); -} - - - - - -/** - * psppire_sheet_model_is_editable: - * @sheet_model: A #PsppireSheetModel - * @row: The row - * @column: The column - * - * Returns: TRUE if the cell is editable, FALSE otherwise - **/ -gboolean -psppire_sheet_model_is_editable (const PsppireSheetModel *model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), TRUE); - - if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable ) - return TRUE; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->is_editable (model, - row, column); -} - - -/** - * psppire_sheet_model_get_foreground: - * @sheet_model: A #PsppireSheetModel - * @row: The row - * @column: The column - * - * Returns the foreground colour of the cell at @row, @column - * The color is unallocated. It will be allocated by the viewing object. - **/ -GdkColor * -psppire_sheet_model_get_foreground (const PsppireSheetModel *model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground ) - return NULL; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_foreground (model, - row, column); -} - -/** - * psppire_sheet_model_get_background: - * @sheet_model: A #PsppireSheetModel - * @row: The row - * @column: The column - * - * Returns the background colour of the cell at @row, @column - * The color is unallocated. It will be allocated by the viewing object. - **/ -GdkColor * -psppire_sheet_model_get_background (const PsppireSheetModel *model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background ) - return NULL; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_background (model, - row, column); -} - -/** - * psppire_sheet_model_get_justification: - * @sheet_model: A #PsppireSheetModel - * @row: The row - * @column: The column - * - * Returns the justification of the cell at @row, @column - * Returns: the justification, or NULL on error. - **/ -const GtkJustification * -psppire_sheet_model_get_justification (const PsppireSheetModel *model, - glong row, glong column) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( ! PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification) - return NULL; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_justification (model, - row, column); -} - - -/** - * psppire_sheet_model_get_column_count: - * @model: A #PsppireSheetModel - * - * Returns the total number of columns represented by the model - **/ -glong -psppire_sheet_model_get_column_count (const PsppireSheetModel *model) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1); - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_count (model); -} - -/** - * psppire_sheet_model_get_row_count: - * @model: A #PsppireSheetModel - * - * Returns the total number of rows represented by the model - **/ -gint -psppire_sheet_model_get_row_count(const PsppireSheetModel *model) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), -1); - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_count (model); -} - - - -/* Column related functions */ -gboolean -psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model, gint col) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE); - - if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity) - return TRUE; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_sensitivity (model, col); -} - - -gchar * -psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model, - gint col) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - g_return_val_if_fail (col >= 0, NULL); - - if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle) - return NULL; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_subtitle (model, col); -} - - -PsppireSheetButton * -psppire_sheet_model_get_column_button (const PsppireSheetModel *model, - gint col) -{ - PsppireSheetButton *button = psppire_sheet_button_new (); - - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title) - button->label = PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_title (model, col); - - button->overstruck = FALSE; - - return button; -} - -GtkJustification -psppire_sheet_model_get_column_justification (const PsppireSheetModel *model, - gint col) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), GTK_JUSTIFY_LEFT); - - if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification) - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_column_justification (model, col); - - return GTK_JUSTIFY_LEFT; -} - - - -gboolean -psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model, gint row) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), FALSE); - - if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity) - return TRUE; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_sensitivity (model, row); -} - - - -gchar * -psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model, - gint row) -{ - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( NULL == PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle) - return NULL; - - return PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_subtitle (model, row); -} - - -PsppireSheetButton * -psppire_sheet_model_get_row_button (const PsppireSheetModel *model, - gint row) -{ - PsppireSheetButton *button = psppire_sheet_button_new (); - - g_return_val_if_fail (PSPPIRE_IS_SHEET_MODEL (model), NULL); - - if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title) - button->label = - PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_title (model, row); - - if ( PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_overstrike) - button->overstruck = - PSPPIRE_SHEET_MODEL_GET_IFACE (model)->get_row_overstrike (model, row); - - return button; -} - diff --git a/src/ui/gui/sheet/psppire-sheetmodel.h b/src/ui/gui/sheet/psppire-sheetmodel.h deleted file mode 100644 index c8519077be..0000000000 --- a/src/ui/gui/sheet/psppire-sheetmodel.h +++ /dev/null @@ -1,223 +0,0 @@ -/* PsppireSheetModel --- an abstract model for the PsppireSheet widget. - * Copyright (C) 2006, 2008 Free Software Foundation - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef __PSPPIRE_SHEET_MODEL_H__ -#define __PSPPIRE_SHEET_MODEL_H__ - - -/* This file provides an abstract interface or the data displayed by the - PsppireSheet widget */ - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define PSPPIRE_TYPE_SHEET_MODEL (psppire_sheet_model_get_type ()) -#define PSPPIRE_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModel)) -#define PSPPIRE_IS_SHEET_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_SHEET_MODEL)) -#define PSPPIRE_SHEET_MODEL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_SHEET_MODEL, PsppireSheetModelIface)) - -typedef enum -{ - PSPPIRE_SHEET_LEFT_BORDER = 1 << 0, - PSPPIRE_SHEET_RIGHT_BORDER = 1 << 1, - PSPPIRE_SHEET_TOP_BORDER = 1 << 2, - PSPPIRE_SHEET_BOTTOM_BORDER = 1 << 3 -} PsppireSheetBorderType ; - - -typedef struct _PsppireSheetModel PsppireSheetModel; /* Dummy typedef */ -typedef struct _PsppireSheetModelIface PsppireSheetModelIface; -typedef struct _PsppireSheetRange PsppireSheetRange; -typedef struct _PsppireSheetCellBorder PsppireSheetCellBorder; - -struct _PsppireSheetRange -{ - gint row0, col0; /* upper-left cell */ - gint rowi, coli; /* lower-right cell */ -}; - -struct _PsppireSheetCellBorder -{ - PsppireSheetBorderType mask; - guint width; - GdkLineStyle line_style; - GdkCapStyle cap_style; - GdkJoinStyle join_style; - GdkColor color; -}; - - - -struct _PsppireSheetModelIface -{ - GTypeInterface g_iface; - - gboolean free_strings; - - /* Signals */ - void (* range_changed) (PsppireSheetModel *sheet_model, - glong row0, glong col0, - glong rowi, glong coli); - - void (* rows_inserted) (PsppireSheetModel *sheet_model, - glong row, glong n_rows); - - void (* rows_deleted) (PsppireSheetModel *sheet_model, - glong row, glong n_rows); - - void (* columns_inserted) (PsppireSheetModel *sheet_model, - glong column, glong n_columns); - - void (* columns_deleted) (PsppireSheetModel *sheet_model, - glong column, glong n_columns); - - - - /* Virtual Table */ - - gchar * (* get_string) (const PsppireSheetModel *sheet_model, - glong row, glong column); - - gboolean (* set_string) (PsppireSheetModel *sheet_model, - const gchar *s, glong row, glong column); - - gboolean (* clear_datum) (PsppireSheetModel *sheet_model, - glong row, glong column); - - gboolean (* is_editable) (const PsppireSheetModel *sheet_model, glong row, glong column); - - GdkColor * (* get_foreground) (const PsppireSheetModel *sheet_model, - glong row, glong column); - - GdkColor * (* get_background) (const PsppireSheetModel *sheet_model, - glong row, glong column); - - const GtkJustification * (* get_justification) (const PsppireSheetModel *sheet_model, - glong row, glong column); - - /* column related metadata */ - - gchar * (*get_column_title) (const PsppireSheetModel *, gint col); - gchar * (*get_column_subtitle) (const PsppireSheetModel *, gint col); - gboolean (*get_column_sensitivity) (const PsppireSheetModel *, gint col); - GtkJustification (*get_column_justification) (const PsppireSheetModel *mode, gint col); - const PsppireSheetButton * (* get_button) (const PsppireSheetModel *model, gint col); - - glong (*get_column_count) (const PsppireSheetModel *model); - - - /* row related metadata */ - gchar * (*get_row_title) (const PsppireSheetModel *, gint row); - gchar * (*get_row_subtitle) (const PsppireSheetModel *, gint row); - glong (*get_row_count) (const PsppireSheetModel *model); - gboolean (*get_row_sensitivity) (const PsppireSheetModel *, gint row); - - gboolean (*get_row_overstrike) (const PsppireSheetModel *, gint row); -}; - - - -GType psppire_sheet_model_get_type (void) G_GNUC_CONST; - - -gchar * psppire_sheet_model_get_string (const PsppireSheetModel *sheet_model, - glong row, glong column); - -gboolean psppire_sheet_model_set_string (PsppireSheetModel *sheet_model, - const gchar *s, - glong row, glong column); - -gboolean psppire_sheet_model_datum_clear (PsppireSheetModel *sheet_model, - glong row, glong column); - - -void psppire_sheet_model_range_changed (PsppireSheetModel *sheet_model, - glong row0, glong col0, - glong rowi, glong coli); - -void psppire_sheet_model_rows_deleted (PsppireSheetModel *sheet_model, - glong row, glong n_rows); - -void psppire_sheet_model_rows_inserted (PsppireSheetModel *sheet_model, - glong row, glong n_rows); - -void psppire_sheet_model_columns_inserted (PsppireSheetModel *sheet_model, - glong column, glong n_columns); - -void psppire_sheet_model_columns_deleted (PsppireSheetModel *sheet_model, - glong column, glong n_columns); - - -gboolean psppire_sheet_model_is_editable (const PsppireSheetModel *model, - glong row, glong column); - -gboolean psppire_sheet_model_is_visible - (const PsppireSheetModel *model, glong row, glong column); - - -GdkColor *psppire_sheet_model_get_foreground - (const PsppireSheetModel *model, glong row, glong column); - -GdkColor *psppire_sheet_model_get_background - (const PsppireSheetModel *model, glong row, glong column); - -const GtkJustification *psppire_sheet_model_get_justification - (const PsppireSheetModel *model, glong row, glong column); - -const PsppireSheetCellBorder * psppire_sheet_model_get_cell_border - (const PsppireSheetModel *model, glong row, glong column); - -gboolean psppire_sheet_model_free_strings (const PsppireSheetModel *sheet_model); - -glong psppire_sheet_model_get_column_count (const PsppireSheetModel *sheet_model); - -gint psppire_sheet_model_get_row_count (const PsppireSheetModel *sheet_model); - - - -gboolean psppire_sheet_model_get_column_sensitivity (const PsppireSheetModel *model, - gint col); - -gchar * psppire_sheet_model_get_column_subtitle (const PsppireSheetModel *model, - gint col); - -PsppireSheetButton * psppire_sheet_model_get_column_button (const PsppireSheetModel *, gint); - -GtkJustification psppire_sheet_model_get_column_justification (const PsppireSheetModel *, - gint); - - - -gboolean psppire_sheet_model_get_row_sensitivity (const PsppireSheetModel *model, - gint row); - - -gchar * psppire_sheet_model_get_row_subtitle (const PsppireSheetModel *model, - gint row); - - -PsppireSheetButton * psppire_sheet_model_get_row_button (const PsppireSheetModel *, gint); - - - - -G_END_DECLS - -#endif /* __PSPPIRE_SHEET_MODEL_H__ */