X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fgtksheet%2Fgtksheet.c;h=3c1f32252a1eab199cf0dc3c23216baf9854f7e4;hb=bc632e6f82af2edb7e1c3f9feb9901deaa5038c0;hp=3a6da7ecb3af10fbd63c62787fa12d4dc6c921a8;hpb=00f87914f662b50bcb9eaf432e10ef5c3f486086;p=pspp diff --git a/lib/gtksheet/gtksheet.c b/lib/gtksheet/gtksheet.c index 3a6da7ecb3..3c1f32252a 100644 --- a/lib/gtksheet/gtksheet.c +++ b/lib/gtksheet/gtksheet.c @@ -34,15 +34,8 @@ * * GtkSheet is a matrix widget for GTK+. It consists of an scrollable grid of * cells where you can allocate text. Cell contents can be edited interactively - * through a specially designed entry, GtkItemEntry. It is also a container - * subclass, allowing you to display buttons, curves, pixmaps and any other - * widgets in it. + * through a specially designed entry, GtkItemEntry. * - * You can also set many attributes as: border, foreground and background color, - * text justification, and more. - * - * The testgtksheet program shows how easy is to create a spreadsheet-like GUI - * using this widget. */ #include @@ -53,65 +46,62 @@ #include #include #include -#include #include #include -#include -#include -#include #include #include #include -#include #include -#include "gtkitementry.h" #include "gtksheet.h" -#include "gtkextra-marshal.h" +#include #include "gsheetmodel.h" +#include +#include /* sheet flags */ enum { - GTK_SHEET_IS_FROZEN = 1 << 1, - GTK_SHEET_IN_XDRAG = 1 << 2, - GTK_SHEET_IN_YDRAG = 1 << 3, - GTK_SHEET_IN_DRAG = 1 << 4, - GTK_SHEET_IN_SELECTION = 1 << 5, - GTK_SHEET_IN_RESIZE = 1 << 6, - GTK_SHEET_REDRAW_PENDING = 1 << 7, + GTK_SHEET_IN_XDRAG = 1 << 1, + GTK_SHEET_IN_YDRAG = 1 << 2, + GTK_SHEET_IN_DRAG = 1 << 3, + GTK_SHEET_IN_SELECTION = 1 << 4, + GTK_SHEET_IN_RESIZE = 1 << 5 }; #define GTK_SHEET_FLAGS(sheet) (GTK_SHEET (sheet)->flags) #define GTK_SHEET_SET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) |= (flag)) #define GTK_SHEET_UNSET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) &= ~ (flag)) -#define GTK_SHEET_IS_FROZEN(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN) #define GTK_SHEET_IN_XDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG) #define GTK_SHEET_IN_YDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG) #define GTK_SHEET_IN_DRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_DRAG) #define GTK_SHEET_IN_SELECTION(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_SELECTION) #define GTK_SHEET_IN_RESIZE(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_RESIZE) -#define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING) #define CELL_SPACING 1 -#define DRAG_WIDTH 6 + #define TIMEOUT_HOVER 300 -#define TIME_INTERVAL 8 #define COLUMN_MIN_WIDTH 10 -#define MINROWS 1 -#define MINCOLS 1 -#define MAXLENGTH 30 -#define CELLOFFSET 4 +#define COLUMN_TITLES_HEIGHT 4 #define DEFAULT_COLUMN_WIDTH 80 +#define DEFAULT_ROW_HEIGHT 25 +static void set_entry_widget_font (GtkSheet *sheet); static void gtk_sheet_update_primary_selection (GtkSheet *sheet); -static void gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column); +static void draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint n); +static void draw_row_title_buttons_range (GtkSheet *sheet, gint first, gint n); + -static void gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row); +static void gtk_sheet_set_row_height (GtkSheet *sheet, + gint row, + guint height); +static void destroy_hover_window (GtkSheetHoverTitle *); +static GtkSheetHoverTitle *create_hover_window (void); + +static GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col); -static gboolean gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col); static inline void dispose_string (const GtkSheet *sheet, gchar *text) @@ -125,402 +115,137 @@ dispose_string (const GtkSheet *sheet, gchar *text) g_free (text); } -static inline -guint DEFAULT_ROW_HEIGHT (GtkWidget *widget) -{ - if (!widget->style->font_desc) return 24; - else - { - PangoContext *context = gtk_widget_get_pango_context (widget); - PangoFontMetrics *metrics = - pango_context_get_metrics (context, - widget->style->font_desc, - pango_context_get_language (context)); - - guint val = pango_font_metrics_get_descent (metrics) + - pango_font_metrics_get_ascent (metrics); - - pango_font_metrics_unref (metrics); - - return PANGO_PIXELS (val) + 2 * CELLOFFSET; - } -} - -static inline -guint DEFAULT_FONT_ASCENT (GtkWidget *widget) -{ - if (!widget->style->font_desc) return 12; - else - { - PangoContext *context = gtk_widget_get_pango_context (widget); - PangoFontMetrics *metrics = - pango_context_get_metrics (context, - widget->style->font_desc, - pango_context_get_language (context)); - guint val = pango_font_metrics_get_ascent (metrics); - pango_font_metrics_unref (metrics); - return PANGO_PIXELS (val); - } -} - -static inline -guint STRING_WIDTH (GtkWidget *widget, - const PangoFontDescription *font, const gchar *text) -{ - PangoRectangle rect; - PangoLayout *layout; - - layout = gtk_widget_create_pango_layout (widget, text); - pango_layout_set_font_description (layout, font); - - pango_layout_get_extents (layout, NULL, &rect); - - g_object_unref (layout); - return PANGO_PIXELS (rect.width); -} - -static inline -guint DEFAULT_FONT_DESCENT (GtkWidget *widget) -{ - if (!widget->style->font_desc) return 12; - else - { - PangoContext *context = gtk_widget_get_pango_context (widget); - PangoFontMetrics *metrics = - pango_context_get_metrics (context, - widget->style->font_desc, - pango_context_get_language (context)); - guint val = pango_font_metrics_get_descent (metrics); - pango_font_metrics_unref (metrics); - return PANGO_PIXELS (val); - } -} - - -static gint -yyy_row_is_visible (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_visibility (row_geo, row, 0); -} - - -static gint -yyy_row_is_sensitive (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_sensitivity (row_geo, row, 0); -} - - - -static inline gint -yyy_row_count (const GtkSheet *sheet) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_row_count (row_geo, 0); -} - -static inline gint -yyy_row_height (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_height (row_geo, row, 0); -} - -static gint -yyy_row_top_ypixel (const GtkSheet *sheet, gint row) -{ - GSheetRow *geo = sheet->row_geometry; - - gint y = g_sheet_row_start_pixel (geo, row, 0); - - if ( sheet->column_titles_visible ) - y += sheet->column_title_area.height; - - return y; -} - - -/* Return the row containing pixel Y */ -static gint -yyy_row_ypixel_to_row (const GtkSheet *sheet, gint y) -{ - GSheetRow *geo = sheet->row_geometry; - - gint cy = sheet->voffset; - - if (sheet->column_titles_visible) - cy += sheet->column_title_area.height; - - if (y < cy) return 0; - - return g_sheet_row_pixel_to_row (geo, y - cy, 0); -} +/* FIXME: Why bother with these two ? */ -/* gives the top pixel of the given row in context of - * the sheet's voffset */ +/* returns the column index from a pixel location */ static inline gint -ROW_TOP_YPIXEL (const GtkSheet *sheet, gint row) +column_from_xpixel (const GtkSheet *sheet, gint pixel) { - return (sheet->voffset + yyy_row_top_ypixel (sheet, row)); + return psppire_axis_get_unit_at_pixel (sheet->haxis, pixel); } - -/* returns the row index from a y pixel location in the - * context of the sheet's voffset */ static inline gint -ROW_FROM_YPIXEL (const GtkSheet *sheet, gint y) -{ - return (yyy_row_ypixel_to_row (sheet, y)); -} - -static inline GtkSheetButton * -xxx_column_button (const GtkSheet *sheet, gint col) +row_from_ypixel (const GtkSheet *sheet, gint pixel) { - GSheetColumn *col_geo = sheet->column_geometry; - if ( col < 0 ) return NULL ; - - return g_sheet_column_get_button (col_geo, col); + return psppire_axis_get_unit_at_pixel (sheet->vaxis, pixel); } -static inline gint -xxx_column_left_xpixel (const GtkSheet *sheet, gint col) +/* Return the lowest row number which is wholly or partially on + the visible range of the sheet */ +static inline glong +min_visible_row (const GtkSheet *sheet) { - GSheetColumn *geo = sheet->column_geometry; - - gint x = g_sheet_column_start_pixel (geo, col); - - if ( sheet->row_titles_visible ) - x += sheet->row_title_area.width; - - return x; + return row_from_ypixel (sheet, sheet->vadjustment->value); } -static inline gint -xxx_column_width (const GtkSheet *sheet, gint col) +static inline glong +min_fully_visible_row (const GtkSheet *sheet) { - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_width (col_geo, col); -} + glong row = min_visible_row (sheet); + if ( psppire_axis_pixel_start (sheet->vaxis, row) < sheet->vadjustment->value) + row++; -static inline void -xxx_set_column_width (GtkSheet *sheet, gint col, gint width) -{ - if ( sheet->column_geometry ) - g_sheet_column_set_width (sheet->column_geometry, col, width); + return row; } -static inline void -xxx_column_set_left_column (GtkSheet *sheet, gint col, gint i) +static inline glong +max_visible_row (const GtkSheet *sheet) { - GSheetColumn *col_geo = sheet->column_geometry; - - g_sheet_column_set_left_text_column (col_geo, col, i); + return row_from_ypixel (sheet, + sheet->vadjustment->value + + sheet->vadjustment->page_size); } -static inline gint -xxx_column_left_column (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_left_text_column (col_geo, col); -} -static inline void -xxx_column_set_right_column (GtkSheet *sheet, gint col, gint i) +static inline glong +max_fully_visible_row (const GtkSheet *sheet) { - GSheetColumn *col_geo = sheet->column_geometry; + glong row = max_visible_row (sheet); - g_sheet_column_set_right_text_column (col_geo, col, i); -} - -static inline gint -xxx_column_right_column (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; + if ( psppire_axis_pixel_start (sheet->vaxis, row) + + + psppire_axis_unit_size (sheet->vaxis, row) + > sheet->vadjustment->value) + row--; - return g_sheet_column_get_right_text_column (col_geo, col); + return row; } -static inline GtkJustification -xxx_column_justification (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_justification (col_geo, col); -} -static inline gint -xxx_column_is_visible (const GtkSheet *sheet, gint col) +/* Returns the lowest column number which is wholly or partially + on the sheet */ +static inline glong +min_visible_column (const GtkSheet *sheet) { - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_visibility (col_geo, col); + return column_from_xpixel (sheet, sheet->hadjustment->value); } - -static inline gint -xxx_column_is_sensitive (const GtkSheet *sheet, gint col) +static inline glong +min_fully_visible_column (const GtkSheet *sheet) { - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_sensitivity (col_geo, col); -} + glong col = min_visible_column (sheet); + if ( psppire_axis_pixel_start (sheet->haxis, col) < sheet->hadjustment->value) + col++; -/* gives the left pixel of the given column in context of - * the sheet's hoffset */ -static inline gint -COLUMN_LEFT_XPIXEL (const GtkSheet *sheet, gint ncol) -{ - return (sheet->hoffset + xxx_column_left_xpixel (sheet, ncol)); + return col; } -static inline gint -xxx_column_count (const GtkSheet *sheet) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_column_count (col_geo); -} -/* returns the column index from a x pixel location in the - * context of the sheet's hoffset */ -static inline gint -COLUMN_FROM_XPIXEL (const GtkSheet * sheet, - gint x) +/* Returns the highest column number which is wholly or partially + on the sheet */ +static inline glong +max_visible_column (const GtkSheet *sheet) { - gint i, cx; - - cx = sheet->hoffset; - if ( sheet->row_titles_visible ) - cx += sheet->row_title_area.width; - - if (x < cx) return 0; - for (i = 0; i < xxx_column_count (sheet); i++) - { - if (x >= cx && x <= (cx + xxx_column_width (sheet, i)) && - xxx_column_is_visible (sheet, i)) - return i; - if ( xxx_column_is_visible (sheet, i)) - cx += xxx_column_width (sheet, i); - } - - /* no match */ - return xxx_column_count (sheet) - 1; + return column_from_xpixel (sheet, + sheet->hadjustment->value + + sheet->hadjustment->page_size); } -/* returns the total height of the sheet */ -static inline gint SHEET_HEIGHT (GtkSheet *sheet) +static inline glong +max_fully_visible_column (const GtkSheet *sheet) { - const gint n_rows = yyy_row_count (sheet); - - return yyy_row_top_ypixel (sheet, n_rows - 1) + - yyy_row_height (sheet, n_rows - 1); -} - + glong col = max_visible_column (sheet); -static inline GtkSheetButton * -yyy_row_button (GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; + if ( psppire_axis_pixel_start (sheet->haxis, col) + + + psppire_axis_unit_size (sheet->haxis, col) + > sheet->hadjustment->value) + col--; - return g_sheet_row_get_button (row_geo, row, sheet); + 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 inline void -yyy_set_row_height (GtkSheet *sheet, gint row, gint height) -{ - if ( sheet->row_geometry ) - g_sheet_row_set_height (sheet->row_geometry, row, height, sheet); -} - - - -/* returns the total width of the sheet */ -static inline gint SHEET_WIDTH (GtkSheet *sheet) +static gboolean +on_column_boundary (const GtkSheet *sheet, gint x, gint *column) { - gint i, cx; - - cx = ( sheet->row_titles_visible ? sheet->row_title_area.width : 0); - - for (i = 0; i < xxx_column_count (sheet); i++) - if (xxx_column_is_visible (sheet, i)) - cx += xxx_column_width (sheet, i); - - return cx; -} - -#define MIN_VISIBLE_ROW(sheet) \ - ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1) - -#define MAX_VISIBLE_ROW(sheet) \ - ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1) - -#define MIN_VISIBLE_COLUMN(sheet) \ - COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1) - -#define MAX_VISIBLE_COLUMN(sheet) \ - COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width) - - + gint col; -static inline gboolean -POSSIBLE_XDRAG (const GtkSheet *sheet, gint x, gint *drag_column) -{ - gint column, xdrag; + x += sheet->hadjustment->value; - column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_column = column; + col = column_from_xpixel (sheet, x); - xdrag = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING; - if (x <= xdrag + DRAG_WIDTH / 2 && column != 0) + if ( column_from_xpixel (sheet, x - DRAG_WIDTH / 2) < col ) { - while (! xxx_column_is_visible (sheet, column - 1) && column > 0) column--; - *drag_column = column - 1; - return xxx_column_is_sensitive (sheet, column - 1); + *column = col - 1; + return TRUE; } - xdrag += xxx_column_width (sheet, column); - if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) - return xxx_column_is_sensitive (sheet, column); - - return FALSE; -} - -static inline gboolean -POSSIBLE_YDRAG (const GtkSheet *sheet, gint y, gint *drag_row) -{ - gint row, ydrag; - row = ROW_FROM_YPIXEL (sheet, y); - *drag_row = row; - - ydrag = ROW_TOP_YPIXEL (sheet, row)+CELL_SPACING; - if (y <= ydrag + DRAG_WIDTH / 2 && row != 0) + if ( column_from_xpixel (sheet, x + DRAG_WIDTH / 2) > col ) { - while (!yyy_row_is_visible (sheet, row - 1) && row > 0) row--; - *drag_row = row - 1; - return yyy_row_is_sensitive (sheet, row - 1); + *column = col; + return TRUE; } - ydrag +=yyy_row_height (sheet, row); - - if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) - return yyy_row_is_sensitive (sheet, row); - - return FALSE; } @@ -535,21 +260,21 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, sheet->range.col0 < 0 || sheet->range.coli < 0 ) return FALSE; - *drag_column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_row = ROW_FROM_YPIXEL (sheet, y); + *drag_column = column_from_xpixel (sheet, x); + *drag_row = row_from_ypixel (sheet, y); - if (x >= COLUMN_LEFT_XPIXEL (sheet, sheet->range.col0) - DRAG_WIDTH / 2 && - x <= COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli) + - xxx_column_width (sheet, sheet->range.coli) + DRAG_WIDTH / 2) + if (x >= psppire_axis_pixel_start (sheet->haxis, sheet->range.col0) - DRAG_WIDTH / 2 && + x <= psppire_axis_pixel_start (sheet->haxis, sheet->range.coli) + + psppire_axis_unit_size (sheet->haxis, sheet->range.coli) + DRAG_WIDTH / 2) { - ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.row0); + ydrag = psppire_axis_pixel_start (sheet->vaxis, sheet->range.row0); if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) { *drag_row = sheet->range.row0; return TRUE; } - ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.rowi) + - yyy_row_height (sheet, sheet->range.rowi); + ydrag = psppire_axis_pixel_start (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; @@ -557,18 +282,18 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, } } - if (y >= ROW_TOP_YPIXEL (sheet, sheet->range.row0) - DRAG_WIDTH / 2 && - y <= ROW_TOP_YPIXEL (sheet, sheet->range.rowi) + - yyy_row_height (sheet, sheet->range.rowi) + DRAG_WIDTH / 2) + if (y >= psppire_axis_pixel_start (sheet->vaxis, sheet->range.row0) - DRAG_WIDTH / 2 && + y <= psppire_axis_pixel_start (sheet->vaxis, sheet->range.rowi) + + psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi) + DRAG_WIDTH / 2) { - xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.col0); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.col0); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) { *drag_column = sheet->range.col0; return TRUE; } - xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli) + - xxx_column_width (sheet, sheet->range.coli); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.coli) + + psppire_axis_unit_size (sheet->haxis, sheet->range.coli); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) { *drag_column = sheet->range.coli; @@ -590,20 +315,20 @@ POSSIBLE_RESIZE (const GtkSheet *sheet, gint x, gint y, sheet->range.col0 < 0 || sheet->range.coli < 0 ) return FALSE; - xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli)+ - xxx_column_width (sheet, sheet->range.coli); + xdrag = psppire_axis_pixel_start (sheet->haxis, sheet->range.coli)+ + psppire_axis_unit_size (sheet->haxis, sheet->range.coli); - ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.rowi)+ - yyy_row_height (sheet, sheet->range.rowi); + ydrag = psppire_axis_pixel_start (sheet->vaxis, sheet->range.rowi) + + psppire_axis_unit_size (sheet->vaxis, sheet->range.rowi); if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - ydrag = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet)); + ydrag = psppire_axis_pixel_start (sheet->vaxis, min_visible_row (sheet)); if (sheet->state == GTK_SHEET_ROW_SELECTED) - xdrag = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet)); + xdrag = psppire_axis_pixel_start (sheet->haxis, min_visible_column (sheet)); - *drag_column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_row = ROW_FROM_YPIXEL (sheet, y); + *drag_column = column_from_xpixel (sheet, x); + *drag_row = row_from_ypixel (sheet, y); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2 && y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) return TRUE; @@ -611,18 +336,65 @@ POSSIBLE_RESIZE (const GtkSheet *sheet, gint x, gint y, return FALSE; } -static void gtk_sheet_class_init (GtkSheetClass * klass); -static void gtk_sheet_init (GtkSheet * sheet); -static void gtk_sheet_dispose (GObject * object); -static void gtk_sheet_finalize (GObject * object); + +static gboolean +rectangle_from_range (GtkSheet *sheet, const GtkSheetRange *range, + GdkRectangle *r) +{ + g_return_val_if_fail (range, FALSE); + + r->x = psppire_axis_pixel_start (sheet->haxis, range->col0); + r->x -= round (sheet->hadjustment->value); + + if ( sheet->row_titles_visible) + r->x += sheet->row_title_area.width; + + + r->y = psppire_axis_pixel_start (sheet->vaxis, range->row0); + r->y -= round (sheet->vadjustment->value); + + if ( sheet->column_titles_visible) + r->y += sheet->column_title_area.height; + + r->width = psppire_axis_pixel_start (sheet->haxis, range->coli) - + psppire_axis_pixel_start (sheet->haxis, range->col0) + + psppire_axis_unit_size (sheet->haxis, range->coli); + + r->height = psppire_axis_pixel_start (sheet->vaxis, range->rowi) - + psppire_axis_pixel_start (sheet->vaxis, range->row0) + + psppire_axis_unit_size (sheet->vaxis, range->rowi); + + return TRUE; +} + +static gboolean +rectangle_from_cell (GtkSheet *sheet, gint row, gint col, + GdkRectangle *r) +{ + GtkSheetRange range; + g_return_val_if_fail (row >= 0, FALSE); + g_return_val_if_fail (col >= 0, FALSE); + + range.row0 = range.rowi = row; + range.col0 = range.coli = col; + + return rectangle_from_range (sheet, &range, r); +} + + +static void gtk_sheet_class_init (GtkSheetClass *klass); +static void gtk_sheet_init (GtkSheet *sheet); +static void gtk_sheet_dispose (GObject *object); +static void gtk_sheet_finalize (GObject *object); static void gtk_sheet_style_set (GtkWidget *widget, GtkStyle *previous_style); -static void gtk_sheet_realize (GtkWidget * widget); -static void gtk_sheet_unrealize (GtkWidget * widget); -static void gtk_sheet_map (GtkWidget * widget); -static void gtk_sheet_unmap (GtkWidget * widget); -static gint gtk_sheet_expose (GtkWidget * widget, - GdkEventExpose * event); +static void gtk_sheet_realize (GtkWidget *widget); +static void gtk_sheet_unrealize (GtkWidget *widget); +static void gtk_sheet_map (GtkWidget *widget); +static void gtk_sheet_unmap (GtkWidget *widget); +static gint gtk_sheet_expose (GtkWidget *widget, + GdkEventExpose *event); + static void gtk_sheet_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, @@ -632,40 +404,38 @@ static void gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); -static gint gtk_sheet_button_press (GtkWidget * widget, - GdkEventButton * event); -static gint gtk_sheet_button_release (GtkWidget * widget, - GdkEventButton * event); -static gint gtk_sheet_motion (GtkWidget * widget, - GdkEventMotion * event); +static gint gtk_sheet_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_sheet_button_release (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_sheet_motion (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gtk_sheet_crossing_notify (GtkWidget *widget, + GdkEventCrossing *event); static gint gtk_sheet_entry_key_press (GtkWidget *widget, GdkEventKey *key); -static gint gtk_sheet_key_press (GtkWidget *widget, +static gboolean gtk_sheet_key_press (GtkWidget *widget, GdkEventKey *key); -static void gtk_sheet_size_request (GtkWidget * widget, - GtkRequisition * requisition); -static void gtk_sheet_size_allocate (GtkWidget * widget, - GtkAllocation * allocation); +static void gtk_sheet_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_sheet_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); /* Sheet queries */ -static gboolean gtk_sheet_range_isvisible (const GtkSheet * sheet, - GtkSheetRange range); -static gboolean gtk_sheet_cell_isvisible (GtkSheet * sheet, +static gboolean gtk_sheet_range_isvisible (const GtkSheet *sheet, + const GtkSheetRange *range); +static gboolean gtk_sheet_cell_isvisible (GtkSheet *sheet, gint row, gint column); /* Drawing Routines */ -/* draw cell background and frame */ -static void gtk_sheet_cell_draw_default (GtkSheet *sheet, - gint row, gint column); +/* draw cell */ +static void gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint column); -/* draw cell contents */ -static void gtk_sheet_cell_draw_label (GtkSheet *sheet, - gint row, gint column); /* draw visible part of range. If range == NULL then draw the whole screen */ -static void gtk_sheet_range_draw (GtkSheet *sheet, - const GtkSheetRange *range); +static void gtk_sheet_range_draw (GtkSheet *sheet, + const GtkSheetRange *range); /* highlight the visible part of the selected range */ static void gtk_sheet_range_draw_selection (GtkSheet *sheet, @@ -673,63 +443,51 @@ static void gtk_sheet_range_draw_selection (GtkSheet *sheet, /* Selection */ -static gboolean gtk_sheet_move_query (GtkSheet *sheet, - gint row, gint column); -static void gtk_sheet_real_select_range (GtkSheet * sheet, - const GtkSheetRange * range); -static void gtk_sheet_real_unselect_range (GtkSheet * sheet, - const GtkSheetRange * range); +static void gtk_sheet_real_select_range (GtkSheet *sheet, + const GtkSheetRange *range); +static void gtk_sheet_real_unselect_range (GtkSheet *sheet, + const GtkSheetRange *range); static void gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column); static void gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range); static void gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange range); -static void gtk_sheet_draw_corners (GtkSheet *sheet, - GtkSheetRange range); - /* Active Cell handling */ static void gtk_sheet_entry_changed (GtkWidget *widget, gpointer data); -static void gtk_sheet_deactivate_cell (GtkSheet *sheet); -static void gtk_sheet_hide_active_cell (GtkSheet *sheet); -static gboolean gtk_sheet_activate_cell (GtkSheet *sheet, - gint row, gint col); +static void gtk_sheet_hide_entry_widget (GtkSheet *sheet); +static void change_active_cell (GtkSheet *sheet, + gint row, gint col); static void gtk_sheet_draw_active_cell (GtkSheet *sheet); -static void gtk_sheet_show_active_cell (GtkSheet *sheet); -static void gtk_sheet_click_cell (GtkSheet *sheet, +static void gtk_sheet_show_entry_widget (GtkSheet *sheet); +static gboolean gtk_sheet_click_cell (GtkSheet *sheet, gint row, - gint column, - gboolean *veto); + gint column); -/* Backing Pixmap */ -static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet, - guint width, guint height); -static void gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, - GtkSheetRange range); /* Scrollbars */ -static void adjust_scrollbars (GtkSheet * sheet); -static void vadjustment_value_changed (GtkAdjustment * adjustment, +static void adjust_scrollbars (GtkSheet *sheet); +static void vadjustment_value_changed (GtkAdjustment *adjustment, gpointer data); -static void hadjustment_value_changed (GtkAdjustment * adjustment, +static void hadjustment_value_changed (GtkAdjustment *adjustment, gpointer data); -static void draw_xor_vline (GtkSheet * sheet); -static void draw_xor_hline (GtkSheet * sheet); +static void draw_xor_vline (GtkSheet *sheet); +static void draw_xor_hline (GtkSheet *sheet); static void draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range); -static guint new_column_width (GtkSheet * sheet, +static guint new_column_width (GtkSheet *sheet, gint column, - gint * x); -static guint new_row_height (GtkSheet * sheet, + gint *x); +static guint new_row_height (GtkSheet *sheet, gint row, - gint * y); + gint *y); /* Sheet Button */ static void create_global_button (GtkSheet *sheet); @@ -739,12 +497,11 @@ static void global_button_clicked (GtkWidget *widget, static void create_sheet_entry (GtkSheet *sheet); static void gtk_sheet_size_allocate_entry (GtkSheet *sheet); -static void gtk_sheet_entry_set_max_size (GtkSheet *sheet); /* Sheet button gadgets */ -static void size_allocate_column_title_buttons (GtkSheet * sheet); -static void size_allocate_row_title_buttons (GtkSheet * sheet); +static void draw_column_title_buttons (GtkSheet *sheet); +static void draw_row_title_buttons (GtkSheet *sheet); static void size_allocate_global_button (GtkSheet *sheet); @@ -752,30 +509,11 @@ static void gtk_sheet_button_size_request (GtkSheet *sheet, const GtkSheetButton *button, GtkRequisition *requisition); -/* Attributes routines */ -static void init_attributes (const GtkSheet *sheet, gint col, - GtkSheetCellAttr *attributes); - - -/* Memory allocation routines */ -static void gtk_sheet_real_range_clear (GtkSheet *sheet, - const GtkSheetRange *range); - static void gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column); -/* Container Functions */ -static void gtk_sheet_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_sheet_realize_child (GtkSheet *sheet, - GtkSheetChild *child); -static void gtk_sheet_position_child (GtkSheet *sheet, - GtkSheetChild *child); -static void gtk_sheet_position_children (GtkSheet *sheet); -static void gtk_sheet_child_show (GtkSheetChild *child); -static void gtk_sheet_child_hide (GtkSheetChild *child); static void gtk_sheet_column_size_request (GtkSheet *sheet, gint col, guint *requisition); @@ -785,10 +523,6 @@ static void gtk_sheet_row_size_request (GtkSheet *sheet, /* Signals */ - -extern void -_gtkextra_signal_emit (GtkObject *object, guint signal_id, ...); - enum { SELECT_ROW, @@ -801,9 +535,7 @@ enum RESIZE_RANGE, MOVE_RANGE, TRAVERSE, - DEACTIVATE, ACTIVATE, - CHANGED, LAST_SIGNAL }; @@ -831,13 +563,16 @@ gtk_sheet_get_type () (GInstanceInitFunc) gtk_sheet_init, NULL, }; + sheet_type = - g_type_register_static (GTK_TYPE_CONTAINER, "GtkSheet", + g_type_register_static (GTK_TYPE_BIN, "GtkSheet", &sheet_info, 0); } return sheet_type; } + + static GtkSheetRange* gtk_sheet_range_copy (const GtkSheetRange *range) { @@ -876,36 +611,76 @@ gtk_sheet_range_get_type (void) return sheet_range_type; } +static GtkSheetCell* +gtk_sheet_cell_copy (const GtkSheetCell *cell) +{ + GtkSheetCell *new_cell; + + g_return_val_if_fail (cell != NULL, NULL); + + new_cell = g_new (GtkSheetCell, 1); + + *new_cell = *cell; + + return new_cell; +} + +static void +gtk_sheet_cell_free (GtkSheetCell *cell) +{ + g_return_if_fail (cell != NULL); + + g_free (cell); +} + +GType +gtk_sheet_cell_get_type (void) +{ + static GType sheet_cell_type = 0; + + if (!sheet_cell_type) + { + sheet_cell_type = + g_boxed_type_register_static ("GtkSheetCell", + (GBoxedCopyFunc) gtk_sheet_cell_copy, + (GBoxedFreeFunc) gtk_sheet_cell_free); + } -static void column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data); + return sheet_cell_type; +} + /* Properties */ enum { PROP_0, - PROP_ROW_GEO, - PROP_COL_GEO, + PROP_VAXIS, + PROP_HAXIS, PROP_MODEL }; static void -gtk_sheet_set_row_geometry (GtkSheet *sheet, GSheetRow *geo) +gtk_sheet_set_horizontal_axis (GtkSheet *sheet, PsppireAxis *a) { - if ( sheet->row_geometry ) g_object_unref (sheet->row_geometry); + if ( sheet->haxis ) + g_object_unref (sheet->haxis); - sheet->row_geometry = geo; + sheet->haxis = a; - if ( sheet->row_geometry ) g_object_ref (sheet->row_geometry); + if ( sheet->haxis ) + g_object_ref (sheet->haxis); } static void -gtk_sheet_set_column_geometry (GtkSheet *sheet, GSheetColumn *geo) +gtk_sheet_set_vertical_axis (GtkSheet *sheet, PsppireAxis *a) { - if ( sheet->column_geometry ) g_object_unref (sheet->column_geometry); + if ( sheet->vaxis ) + g_object_unref (sheet->vaxis); - sheet->column_geometry = geo; + sheet->vaxis = a; - if ( sheet->column_geometry ) g_object_ref (sheet->column_geometry); + if ( sheet->vaxis ) + g_object_ref (sheet->vaxis); } @@ -920,14 +695,11 @@ gtk_sheet_set_property (GObject *object, switch (prop_id) { - case PROP_ROW_GEO: - gtk_sheet_set_row_geometry (sheet, g_value_get_pointer (value)); + case PROP_VAXIS: + gtk_sheet_set_vertical_axis (sheet, g_value_get_pointer (value)); break; - case PROP_COL_GEO: - gtk_sheet_set_column_geometry (sheet, g_value_get_pointer (value)); - if ( sheet->column_geometry) - g_signal_connect (sheet->column_geometry, "columns_changed", - G_CALLBACK (column_titles_changed), sheet); + case PROP_HAXIS: + gtk_sheet_set_horizontal_axis (sheet, g_value_get_pointer (value)); break; case PROP_MODEL: gtk_sheet_set_model (sheet, g_value_get_pointer (value)); @@ -948,11 +720,11 @@ gtk_sheet_get_property (GObject *object, switch (prop_id) { - case PROP_ROW_GEO: - g_value_set_pointer (value, sheet->row_geometry); + case PROP_VAXIS: + g_value_set_pointer (value, sheet->vaxis); break; - case PROP_COL_GEO: - g_value_set_pointer (value, sheet->column_geometry); + case PROP_HAXIS: + g_value_set_pointer (value, sheet->haxis); break; case PROP_MODEL: g_value_set_pointer (value, sheet->model); @@ -965,16 +737,16 @@ gtk_sheet_get_property (GObject *object, static void -gtk_sheet_class_init (GtkSheetClass * klass) +gtk_sheet_class_init (GtkSheetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *row_geo_spec ; - GParamSpec *col_geo_spec ; + GParamSpec *haxis_spec ; + GParamSpec *vaxis_spec ; GParamSpec *model_spec ; - GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; - GtkContainerClass *container_class = (GtkContainerClass *) klass; + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); @@ -1067,7 +839,7 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, - gtkextra_VOID__INT_POINTER, + psppire_marshal_VOID__INT_POINTER, G_TYPE_NONE, 2, G_TYPE_INT, @@ -1088,7 +860,7 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, - gtkextra_VOID__INT_POINTER, + psppire_marshal_VOID__INT_POINTER, G_TYPE_NONE, 2, G_TYPE_INT, @@ -1114,7 +886,7 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, offsetof (GtkSheetClass, resize_range), NULL, NULL, - gtkextra_VOID__BOXED_BOXED, + psppire_marshal_VOID__BOXED_BOXED, G_TYPE_NONE, 2, GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE @@ -1126,7 +898,7 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, offsetof (GtkSheetClass, move_range), NULL, NULL, - gtkextra_VOID__BOXED_BOXED, + psppire_marshal_VOID__BOXED_BOXED, G_TYPE_NONE, 2, GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE @@ -1138,37 +910,22 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, offsetof (GtkSheetClass, traverse), NULL, NULL, - gtkextra_BOOLEAN__INT_INT_POINTER_POINTER, - G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, - G_TYPE_POINTER, G_TYPE_POINTER); + psppire_marshal_BOOLEAN__BOXED_POINTER, + G_TYPE_BOOLEAN, 2, + GTK_TYPE_SHEET_CELL, + G_TYPE_POINTER); - sheet_signals[DEACTIVATE] = - g_signal_new ("deactivate", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (GtkSheetClass, deactivate), - NULL, NULL, - gtkextra_VOID__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - sheet_signals[ACTIVATE] = g_signal_new ("activate", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, offsetof (GtkSheetClass, activate), NULL, NULL, - gtkextra_BOOLEAN__INT_INT, - G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT); - - sheet_signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - offsetof (GtkSheetClass, changed), - NULL, NULL, - gtkextra_VOID__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); + psppire_marshal_VOID__INT_INT_INT_INT, + G_TYPE_NONE, 4, + G_TYPE_INT, G_TYPE_INT, + G_TYPE_INT, G_TYPE_INT); widget_class->set_scroll_adjustments_signal = g_signal_new ("set-scroll-adjustments", @@ -1176,28 +933,28 @@ gtk_sheet_class_init (GtkSheetClass * klass) G_SIGNAL_RUN_LAST, offsetof (GtkSheetClass, set_scroll_adjustments), NULL, NULL, - gtkextra_VOID__OBJECT_OBJECT, + psppire_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); container_class->add = NULL; - container_class->remove = gtk_sheet_remove; + container_class->remove = NULL; container_class->forall = gtk_sheet_forall; object_class->dispose = gtk_sheet_dispose; object_class->finalize = gtk_sheet_finalize; - row_geo_spec = - g_param_spec_pointer ("row-geometry", - "Row Geometry", - "A pointer to the model of the row geometry", + vaxis_spec = + g_param_spec_pointer ("vertical-axis", + "Vertical Axis", + "A pointer to the PsppireAxis object for the rows", G_PARAM_READABLE | G_PARAM_WRITABLE ); - col_geo_spec = - g_param_spec_pointer ("column-geometry", - "Column Geometry", - "A pointer to the model of the column geometry", + haxis_spec = + g_param_spec_pointer ("horizontal-axis", + "Horizontal Axis", + "A pointer to the PsppireAxis object for the columns", G_PARAM_READABLE | G_PARAM_WRITABLE ); model_spec = @@ -1211,12 +968,12 @@ gtk_sheet_class_init (GtkSheetClass * klass) object_class->get_property = gtk_sheet_get_property; g_object_class_install_property (object_class, - PROP_ROW_GEO, - row_geo_spec); + PROP_VAXIS, + vaxis_spec); g_object_class_install_property (object_class, - PROP_COL_GEO, - col_geo_spec); + PROP_HAXIS, + haxis_spec); g_object_class_install_property (object_class, PROP_MODEL, @@ -1231,6 +988,8 @@ gtk_sheet_class_init (GtkSheetClass * klass) widget_class->button_press_event = gtk_sheet_button_press; widget_class->button_release_event = gtk_sheet_button_release; widget_class->motion_notify_event = gtk_sheet_motion; + widget_class->enter_notify_event = gtk_sheet_crossing_notify; + widget_class->leave_notify_event = gtk_sheet_crossing_notify; widget_class->key_press_event = gtk_sheet_key_press; widget_class->expose_event = gtk_sheet_expose; widget_class->size_request = gtk_sheet_size_request; @@ -1245,7 +1004,6 @@ gtk_sheet_class_init (GtkSheetClass * klass) klass->resize_range = NULL; klass->move_range = NULL; klass->traverse = NULL; - klass->deactivate = NULL; klass->activate = NULL; klass->changed = NULL; } @@ -1254,14 +1012,11 @@ static void gtk_sheet_init (GtkSheet *sheet) { sheet->model = NULL; - sheet->column_geometry = NULL; - sheet->row_geometry = NULL; - - sheet->children = NULL; + sheet->haxis = NULL; + sheet->vaxis = NULL; sheet->flags = 0; sheet->selection_mode = GTK_SELECTION_NONE; - sheet->freeze_count = 0; sheet->state = GTK_SHEET_NORMAL; GTK_WIDGET_UNSET_FLAGS (sheet, GTK_NO_WINDOW); @@ -1271,7 +1026,7 @@ gtk_sheet_init (GtkSheet *sheet) sheet->column_title_area.x = 0; sheet->column_title_area.y = 0; sheet->column_title_area.width = 0; - sheet->column_title_area.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); + sheet->column_title_area.height = DEFAULT_ROW_HEIGHT; sheet->row_title_window = NULL; sheet->row_title_area.x = 0; @@ -1285,8 +1040,6 @@ gtk_sheet_init (GtkSheet *sheet) sheet->selection_cell.row = 0; sheet->selection_cell.col = 0; - sheet->pixmap = NULL; - sheet->range.row0 = 0; sheet->range.rowi = 0; sheet->range.col0 = 0; @@ -1295,31 +1048,20 @@ gtk_sheet_init (GtkSheet *sheet) sheet->state = GTK_SHEET_NORMAL; sheet->sheet_window = NULL; - sheet->sheet_window_width = 0; - sheet->sheet_window_height = 0; sheet->entry_widget = NULL; - sheet->entry_container = NULL; + sheet->entry_handler_id = 0; sheet->button = NULL; - sheet->hoffset = 0; - sheet->voffset = 0; - sheet->hadjustment = NULL; sheet->vadjustment = NULL; - sheet->cursor_drag = gdk_cursor_new (GDK_PLUS); + sheet->cursor_drag = NULL; + sheet->xor_gc = NULL; sheet->fg_gc = NULL; sheet->bg_gc = NULL; sheet->x_drag = 0; sheet->y_drag = 0; - gdk_color_parse ("white", &sheet->bg_color); - gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->bg_color, FALSE, - TRUE); - gdk_color_parse ("gray", &sheet->grid_color); - gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->grid_color, FALSE, - TRUE); - sheet->show_grid = TRUE; sheet->motion_timer = 0; @@ -1331,12 +1073,10 @@ gtk_sheet_init (GtkSheet *sheet) sheet->row_title_area.width = DEFAULT_COLUMN_WIDTH; sheet->column_titles_visible = TRUE; - sheet->autoscroll = TRUE; - sheet->justify_entry = TRUE; /* create sheet entry */ - sheet->entry_type = 0; + sheet->entry_type = GTK_TYPE_ENTRY; create_sheet_entry (sheet); /* create global selection button */ @@ -1350,7 +1090,6 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column, gint n_columns, gpointer data) { - gint i; GtkSheet *sheet = GTK_SHEET (data); GtkSheetRange range; @@ -1362,16 +1101,16 @@ columns_inserted_deleted_callback (GSheetModel *model, gint first_column, */ range.col0 = first_column; range.row0 = 0; - range.coli = xxx_column_count (sheet) - 1; - range.rowi = yyy_row_count (sheet) - 1; + range.coli = psppire_axis_unit_count (sheet->haxis) - 1; + range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1; adjust_scrollbars (sheet); if (sheet->active_cell.col >= model_columns) - gtk_sheet_activate_cell (sheet, sheet->active_cell.row, model_columns - 1); + change_active_cell (sheet, sheet->active_cell.row, model_columns - 1); - for (i = first_column; i <= MAX_VISIBLE_COLUMN (sheet); i++) - gtk_sheet_column_title_button_draw (sheet, i); + draw_column_title_buttons_range (sheet, + first_column, max_visible_column (sheet)); gtk_sheet_range_draw (sheet, &range); } @@ -1382,7 +1121,6 @@ static void rows_inserted_deleted_callback (GSheetModel *model, gint first_row, gint n_rows, gpointer data) { - gint i; GtkSheet *sheet = GTK_SHEET (data); GtkSheetRange range; @@ -1394,16 +1132,15 @@ rows_inserted_deleted_callback (GSheetModel *model, gint first_row, */ range.row0 = first_row; range.col0 = 0; - range.rowi = yyy_row_count (sheet) - 1; - range.coli = xxx_column_count (sheet) - 1; + range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1; + range.coli = psppire_axis_unit_count (sheet->haxis) - 1; adjust_scrollbars (sheet); if (sheet->active_cell.row >= model_rows) - gtk_sheet_activate_cell (sheet, model_rows - 1, sheet->active_cell.col); + change_active_cell (sheet, model_rows - 1, sheet->active_cell.col); - for (i = first_row; i <= MAX_VISIBLE_ROW (sheet); i++) - gtk_sheet_row_title_button_draw (sheet, i); + draw_row_title_buttons_range (sheet, first_row, max_visible_row (sheet)); gtk_sheet_range_draw (sheet, &range); } @@ -1425,39 +1162,38 @@ range_update_callback (GSheetModel *m, gint row0, gint col0, range.rowi = rowi; range.coli = coli; - if ( MAX_VISIBLE_ROW (sheet) > - g_sheet_model_get_row_count (sheet->model) + if ( !GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + return; + + if ( max_visible_row (sheet) > g_sheet_model_get_row_count (sheet->model) || - MAX_VISIBLE_COLUMN (sheet) > - g_sheet_model_get_column_count (sheet->model)) + max_visible_column (sheet) > g_sheet_model_get_column_count (sheet->model)) { - gtk_sheet_move_query (sheet, 0, 0); + gtk_sheet_moveto (sheet, 0, 0, 0, 0); } if ( ( row0 < 0 && col0 < 0 ) || ( rowi < 0 && coli < 0 ) ) { - gint i; gtk_sheet_range_draw (sheet, NULL); adjust_scrollbars (sheet); - for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++) - gtk_sheet_row_title_button_draw (sheet, i); + draw_row_title_buttons_range (sheet, min_visible_row (sheet), + max_visible_row (sheet)); - for (i = MIN_VISIBLE_COLUMN (sheet); - i <= MAX_VISIBLE_COLUMN (sheet); i++) - gtk_sheet_column_title_button_draw (sheet, i); + draw_column_title_buttons_range (sheet, min_visible_column (sheet), + max_visible_column (sheet)); return; } else if ( row0 < 0 || rowi < 0 ) { - range.row0 = MIN_VISIBLE_ROW (sheet); - range.rowi = MAX_VISIBLE_ROW (sheet); + range.row0 = min_visible_row (sheet); + range.rowi = max_visible_row (sheet); } else if ( col0 < 0 || coli < 0 ) { - range.col0 = MIN_VISIBLE_COLUMN (sheet); - range.coli = MAX_VISIBLE_COLUMN (sheet); + range.col0 = min_visible_column (sheet); + range.coli = max_visible_column (sheet); } gtk_sheet_range_draw (sheet, &range); @@ -1476,11 +1212,9 @@ range_update_callback (GSheetModel *m, gint row0, gint col0, * Returns: the new sheet widget */ GtkWidget * -gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo, GSheetModel *model) +gtk_sheet_new (GSheetModel *model) { GtkWidget *widget = g_object_new (GTK_TYPE_SHEET, - "row-geometry", vgeo, - "column-geometry", hgeo, "model", model, NULL); return widget; @@ -1526,38 +1260,6 @@ gtk_sheet_set_model (GtkSheet *sheet, GSheetModel *model) } -/* Call back for when the column titles have changed. - FIRST is the first column changed. - N_COLUMNS is the number of columns which have changed, or - 1, which - indicates that the column has changed to its right - most extremity -*/ -static void -column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data) -{ - GtkSheet *sheet = GTK_SHEET (data); - gboolean extremity = FALSE; - - if ( n_columns == -1 ) - { - extremity = TRUE; - n_columns = xxx_column_count (sheet) - 1 ; - } - - if (!GTK_SHEET_IS_FROZEN (sheet)) - { - gint i; - for ( i = first ; i <= first + n_columns ; ++i ) - { - gtk_sheet_column_title_button_draw (sheet, i); - g_signal_emit (sheet, sheet_signals[CHANGED], 0, -1, i); - } - } - - if ( extremity) - gtk_sheet_column_title_button_draw (sheet, -1); - -} - void gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type) { @@ -1569,7 +1271,7 @@ gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type) state = sheet->state; if (sheet->state == GTK_SHEET_NORMAL) - gtk_sheet_hide_active_cell (sheet); + gtk_sheet_hide_entry_widget (sheet); sheet->entry_type = entry_type; @@ -1577,12 +1279,9 @@ gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type) if (state == GTK_SHEET_NORMAL) { - gtk_sheet_show_active_cell (sheet); - g_signal_connect (gtk_sheet_get_entry (sheet), - "changed", - G_CALLBACK (gtk_sheet_entry_changed), - sheet); + gtk_sheet_show_entry_widget (sheet); } + } void @@ -1595,8 +1294,7 @@ gtk_sheet_show_grid (GtkSheet *sheet, gboolean show) sheet->show_grid = show; - if (!GTK_SHEET_IS_FROZEN (sheet)) - gtk_sheet_range_draw (sheet, NULL); + gtk_sheet_range_draw (sheet, NULL); } gboolean @@ -1608,291 +1306,40 @@ gtk_sheet_grid_visible (GtkSheet *sheet) return sheet->show_grid; } -void -gtk_sheet_set_background (GtkSheet *sheet, GdkColor *color) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (!color) - { - gdk_color_parse ("white", &sheet->bg_color); - gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->bg_color, FALSE, TRUE); - } - else - sheet->bg_color = *color; - - if (!GTK_SHEET_IS_FROZEN (sheet)) - gtk_sheet_range_draw (sheet, NULL); -} - -void -gtk_sheet_set_grid (GtkSheet *sheet, GdkColor *color) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (!color) - { - gdk_color_parse ("black", &sheet->grid_color); - gdk_colormap_alloc_color (gdk_colormap_get_system (), &sheet->grid_color, FALSE, TRUE); - } - else - sheet->grid_color = *color; - - if (!GTK_SHEET_IS_FROZEN (sheet)) - gtk_sheet_range_draw (sheet, NULL); -} - -guint -gtk_sheet_get_columns_count (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - - return xxx_column_count (sheet); -} - -guint -gtk_sheet_get_rows_count (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - - return yyy_row_count (sheet); -} - -gint -gtk_sheet_get_state (GtkSheet *sheet) +guint +gtk_sheet_get_columns_count (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - return (sheet->state); -} - -void -gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (GTK_WIDGET_REALIZED (sheet)) - gtk_sheet_real_unselect_range (sheet, NULL); - - sheet->selection_mode = mode; -} - -void -gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->autoresize = autoresize; -} - -gboolean -gtk_sheet_autoresize (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - - return sheet->autoresize; + return psppire_axis_unit_count (sheet->haxis); } static void -gtk_sheet_set_column_width (GtkSheet * sheet, +gtk_sheet_set_column_width (GtkSheet *sheet, gint column, guint width); -static void -gtk_sheet_autoresize_column (GtkSheet *sheet, gint column) -{ - gint text_width = 0; - gint row; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column >= xxx_column_count (sheet) || column < 0) return; - - for (row = 0; row < yyy_row_count (sheet); row++) - { - gchar *text = gtk_sheet_cell_get_text (sheet, row, column); - if (text && strlen (text) > 0) - { - GtkSheetCellAttr attributes; - - gtk_sheet_get_attributes (sheet, row, column, &attributes); - if (attributes.is_visible) - { - gint width = STRING_WIDTH (GTK_WIDGET (sheet), - attributes.font_desc, - text) - + 2 * CELLOFFSET + attributes.border.width; - text_width = MAX (text_width, width); - } - } - dispose_string (sheet, text); - } - - if (text_width > xxx_column_width (sheet, column) ) - { - gtk_sheet_set_column_width (sheet, column, text_width); - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING); - } -} - - -void -gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->autoscroll = autoscroll; -} - -gboolean -gtk_sheet_autoscroll (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - - return sheet->autoscroll; -} - - -void -gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->justify_entry = justify; -} - -gboolean -gtk_sheet_justify_entry (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - - return sheet->justify_entry; -} - - - -void -gtk_sheet_freeze (GtkSheet *sheet) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->freeze_count++; - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); -} - -void -gtk_sheet_thaw (GtkSheet *sheet) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (sheet->freeze_count == 0) return; - - sheet->freeze_count--; - if (sheet->freeze_count > 0) return; - - adjust_scrollbars (sheet); - - GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); - - sheet->old_vadjustment = -1.; - sheet->old_hadjustment = -1.; - - if (sheet->hadjustment) - g_signal_emit_by_name (sheet->hadjustment, - "value_changed"); - if (sheet->vadjustment) - g_signal_emit_by_name (sheet->vadjustment, - "value_changed"); - - if (sheet->state == GTK_STATE_NORMAL) - if (sheet->entry_widget && GTK_WIDGET_MAPPED (sheet->entry_widget)) - { - gtk_sheet_activate_cell (sheet, sheet->active_cell.row, - sheet->active_cell.col); - } - -} - -void -gtk_sheet_set_row_titles_width (GtkSheet *sheet, guint width) -{ - if (width < COLUMN_MIN_WIDTH) return; - - sheet->row_title_area.width = width; - - adjust_scrollbars (sheet); - - sheet->old_hadjustment = -1.; - if (sheet->hadjustment) - g_signal_emit_by_name (sheet->hadjustment, - "value_changed"); - size_allocate_global_button (sheet); -} - -void -gtk_sheet_set_column_titles_height (GtkSheet *sheet, guint height) -{ - if (height < DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))) return; - - sheet->column_title_area.height = height; - - adjust_scrollbars (sheet); - - sheet->old_vadjustment = -1.; - if (sheet->vadjustment) - g_signal_emit_by_name (sheet->vadjustment, - "value_changed"); - size_allocate_global_button (sheet); -} - void gtk_sheet_show_column_titles (GtkSheet *sheet) { - gint col; - if (sheet->column_titles_visible) return; sheet->column_titles_visible = TRUE; + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + return; - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - gdk_window_show (sheet->column_title_window); - gdk_window_move_resize (sheet->column_title_window, - sheet->column_title_area.x, - sheet->column_title_area.y, - sheet->column_title_area.width, - sheet->column_title_area.height); + gdk_window_show (sheet->column_title_window); + gdk_window_move_resize (sheet->column_title_window, + sheet->column_title_area.x, + sheet->column_title_area.y, + sheet->column_title_area.width, + sheet->column_title_area.height); - for (col = MIN_VISIBLE_COLUMN (sheet); - col <= MAX_VISIBLE_COLUMN (sheet); - col++) - { - GtkSheetButton *button = xxx_column_button (sheet, col); - GtkSheetChild *child = button->child; - if (child) - gtk_sheet_child_show (child); - gtk_sheet_button_free (button); - } - adjust_scrollbars (sheet); - } + adjust_scrollbars (sheet); - sheet->old_vadjustment = -1.; if (sheet->vadjustment) g_signal_emit_by_name (sheet->vadjustment, "value_changed"); @@ -1903,8 +1350,6 @@ gtk_sheet_show_column_titles (GtkSheet *sheet) void gtk_sheet_show_row_titles (GtkSheet *sheet) { - gint row; - if (sheet->row_titles_visible) return; sheet->row_titles_visible = TRUE; @@ -1919,22 +1364,9 @@ gtk_sheet_show_row_titles (GtkSheet *sheet) sheet->row_title_area.width, sheet->row_title_area.height); - for (row = MIN_VISIBLE_ROW (sheet); - row <= MAX_VISIBLE_ROW (sheet); - row++) - { - const GtkSheetButton *button = yyy_row_button (sheet, row); - GtkSheetChild *child = button->child; - - if (child) - { - gtk_sheet_child_show (child); - } - } adjust_scrollbars (sheet); } - sheet->old_hadjustment = -1.; if (sheet->hadjustment) g_signal_emit_by_name (sheet->hadjustment, "value_changed"); @@ -1944,8 +1376,6 @@ gtk_sheet_show_row_titles (GtkSheet *sheet) void gtk_sheet_hide_column_titles (GtkSheet *sheet) { - gint col; - if (!sheet->column_titles_visible) return; sheet->column_titles_visible = FALSE; @@ -1957,20 +1387,9 @@ gtk_sheet_hide_column_titles (GtkSheet *sheet) if (GTK_WIDGET_VISIBLE (sheet->button)) gtk_widget_hide (sheet->button); - for (col = MIN_VISIBLE_COLUMN (sheet); - col <= MAX_VISIBLE_COLUMN (sheet); - col++) - { - GtkSheetButton *button = xxx_column_button (sheet, col); - GtkSheetChild *child = button->child; - if (child) - gtk_sheet_child_hide (child); - gtk_sheet_button_free (button); - } adjust_scrollbars (sheet); } - sheet->old_vadjustment = -1.; if (sheet->vadjustment) g_signal_emit_by_name (sheet->vadjustment, "value_changed"); @@ -1979,171 +1398,75 @@ gtk_sheet_hide_column_titles (GtkSheet *sheet) void gtk_sheet_hide_row_titles (GtkSheet *sheet) { - gint row; - if (!sheet->row_titles_visible) return; sheet->row_titles_visible = FALSE; - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) { if (sheet->row_title_window) gdk_window_hide (sheet->row_title_window); + if (GTK_WIDGET_VISIBLE (sheet->button)) gtk_widget_hide (sheet->button); - for (row = MIN_VISIBLE_ROW (sheet); - row <= MAX_VISIBLE_ROW (sheet); - row++) - { - const GtkSheetButton *button = yyy_row_button (sheet, row); - GtkSheetChild *child = button->child; - if (child) - gtk_sheet_child_hide (child); - } adjust_scrollbars (sheet); } - sheet->old_hadjustment = -1.; if (sheet->hadjustment) g_signal_emit_by_name (sheet->hadjustment, "value_changed"); } -gboolean -gtk_sheet_column_titles_visible (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - return sheet->column_titles_visible; -} - -gboolean -gtk_sheet_row_titles_visible (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - return sheet->row_titles_visible; -} +/* Scroll the sheet so that the cell ROW, COLUMN is visible. + If {ROW,COL}_ALIGN is zero, then the cell will be placed + at the {top,left} of the sheet. If it's 1, then it'll + be placed at the {bottom,right}. + ROW or COL may be -1, in which case scrolling in that dimension + does not occur. + */ void gtk_sheet_moveto (GtkSheet *sheet, gint row, - gint column, + gint col, gfloat row_align, gfloat col_align) { - gint x, y; - guint width, height; - gint adjust; - gint min_row, min_col; + gint width, height; - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - g_return_if_fail (sheet->hadjustment != NULL); - g_return_if_fail (sheet->vadjustment != NULL); - - if (row < 0 || row >= yyy_row_count (sheet)) - return; - if (column < 0 || column >= xxx_column_count (sheet)) - return; - - height = sheet->sheet_window_height; - width = sheet->sheet_window_width; - - /* adjust vertical scrollbar */ - if (row >= 0 && row_align >= 0.0) - { - y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset - - (gint) ( row_align * height + (1.0 - row_align) - * yyy_row_height (sheet, row)); - - /* This forces the sheet to scroll when you don't see the entire cell */ - min_row = row; - adjust = 0; - if (row_align >= 1.0) - { - while (min_row >= 0 && min_row > MIN_VISIBLE_ROW (sheet)) - { - if (yyy_row_is_visible (sheet, min_row)) - adjust += yyy_row_height (sheet, min_row); - - if (adjust >= height) - { - break; - } - min_row--; - } - min_row = MAX (min_row, 0); + g_return_if_fail (row_align >= 0); + g_return_if_fail (col_align >= 0); - min_row ++; + g_return_if_fail (row_align <= 1); + g_return_if_fail (col_align <= 1); - y = ROW_TOP_YPIXEL (sheet, min_row) - sheet->voffset + - yyy_row_height (sheet, min_row) - 1; - } + g_return_if_fail (col < + psppire_axis_unit_count (sheet->haxis)); + g_return_if_fail (row < + psppire_axis_unit_count (sheet->vaxis)); - if (y < 0) - sheet->vadjustment->value = 0.0; - else - sheet->vadjustment->value = y; + gdk_drawable_get_size (sheet->sheet_window, &width, &height); - sheet->old_vadjustment = -1.; - g_signal_emit_by_name (sheet->vadjustment, - "value_changed"); - } + if (row >= 0) + { + gint y = psppire_axis_pixel_start (sheet->vaxis, row); - /* adjust horizontal scrollbar */ - if (column >= 0 && col_align >= 0.0) - { - x = COLUMN_LEFT_XPIXEL (sheet, column) - sheet->hoffset - - (gint) ( col_align*width + (1.0 - col_align)* - xxx_column_width (sheet, column)); - - /* This forces the sheet to scroll when you don't see the entire cell */ - min_col = column; - adjust = 0; - if (col_align == 1.0) - { - while (min_col >= 0 && min_col > MIN_VISIBLE_COLUMN (sheet)) - { - if (xxx_column_is_visible (sheet, min_col)) - adjust += xxx_column_width (sheet, min_col); + gtk_adjustment_set_value (sheet->vadjustment, y - height * row_align); + } - if (adjust >= width) - { - break; - } - min_col--; - } - min_col = MAX (min_col, 0); - x = COLUMN_LEFT_XPIXEL (sheet, min_col) - sheet->hoffset + - xxx_column_width (sheet, min_col) - 1; - } - if (x < 0) - sheet->hadjustment->value = 0.0; - else - sheet->hadjustment->value = x; + if (col >= 0) + { + gint x = psppire_axis_pixel_start (sheet->haxis, col); - sheet->old_vadjustment = -1.; - g_signal_emit_by_name (sheet->hadjustment, - "value_changed"); - } + gtk_adjustment_set_value (sheet->hadjustment, x - width * col_align); + } } -void -gtk_sheet_columns_set_resizable (GtkSheet *sheet, gboolean resizable) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->columns_resizable = resizable; -} - -gboolean +static gboolean gtk_sheet_columns_resizable (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); @@ -2153,16 +1476,7 @@ gtk_sheet_columns_resizable (GtkSheet *sheet) } -void -gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - sheet->rows_resizable = resizable; -} - -gboolean +static gboolean gtk_sheet_rows_resizable (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); @@ -2173,25 +1487,22 @@ gtk_sheet_rows_resizable (GtkSheet *sheet) void -gtk_sheet_select_row (GtkSheet * sheet, - gint row) +gtk_sheet_select_row (GtkSheet *sheet, gint row) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (row < 0 || row >= yyy_row_count (sheet)) + if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis)) return; if (sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range (sheet, NULL); - else - gtk_sheet_deactivate_cell (sheet); sheet->state = GTK_SHEET_ROW_SELECTED; sheet->range.row0 = row; sheet->range.col0 = 0; sheet->range.rowi = row; - sheet->range.coli = xxx_column_count (sheet) - 1; + sheet->range.coli = psppire_axis_unit_count (sheet->haxis) - 1; sheet->active_cell.row = row; sheet->active_cell.col = 0; @@ -2201,24 +1512,21 @@ gtk_sheet_select_row (GtkSheet * sheet, void -gtk_sheet_select_column (GtkSheet * sheet, gint column) +gtk_sheet_select_column (GtkSheet *sheet, gint column) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column < 0 || column >= xxx_column_count (sheet)) + if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis)) return; if (sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range (sheet, NULL); - else - gtk_sheet_deactivate_cell (sheet); - sheet->state = GTK_SHEET_COLUMN_SELECTED; sheet->range.row0 = 0; sheet->range.col0 = column; - sheet->range.rowi = yyy_row_count (sheet) - 1; + sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1; sheet->range.coli = column; sheet->active_cell.row = 0; sheet->active_cell.col = column; @@ -2231,40 +1539,40 @@ gtk_sheet_select_column (GtkSheet * sheet, gint column) static gboolean -gtk_sheet_range_isvisible (const GtkSheet * sheet, - GtkSheetRange range) +gtk_sheet_range_isvisible (const GtkSheet *sheet, + const GtkSheetRange *range) { g_return_val_if_fail (sheet != NULL, FALSE); - if (range.row0 < 0 || range.row0 >= yyy_row_count (sheet)) + if (range->row0 < 0 || range->row0 >= psppire_axis_unit_count (sheet->vaxis)) return FALSE; - if (range.rowi < 0 || range.rowi >= yyy_row_count (sheet)) + if (range->rowi < 0 || range->rowi >= psppire_axis_unit_count (sheet->vaxis)) return FALSE; - if (range.col0 < 0 || range.col0 >= xxx_column_count (sheet)) + if (range->col0 < 0 || range->col0 >= psppire_axis_unit_count (sheet->haxis)) return FALSE; - if (range.coli < 0 || range.coli >= xxx_column_count (sheet)) + if (range->coli < 0 || range->coli >= psppire_axis_unit_count (sheet->haxis)) return FALSE; - if (range.rowi < MIN_VISIBLE_ROW (sheet)) + if (range->rowi < min_visible_row (sheet)) return FALSE; - if (range.row0 > MAX_VISIBLE_ROW (sheet)) + if (range->row0 > max_visible_row (sheet)) return FALSE; - if (range.coli < MIN_VISIBLE_COLUMN (sheet)) + if (range->coli < min_visible_column (sheet)) return FALSE; - if (range.col0 > MAX_VISIBLE_COLUMN (sheet)) + if (range->col0 > max_visible_column (sheet)) return FALSE; return TRUE; } static gboolean -gtk_sheet_cell_isvisible (GtkSheet * sheet, +gtk_sheet_cell_isvisible (GtkSheet *sheet, gint row, gint column) { GtkSheetRange range; @@ -2274,7 +1582,7 @@ gtk_sheet_cell_isvisible (GtkSheet * sheet, range.rowi = row; range.coli = column; - return gtk_sheet_range_isvisible (sheet, range); + return gtk_sheet_range_isvisible (sheet, &range); } void @@ -2284,136 +1592,45 @@ gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range) g_return_if_fail (GTK_IS_SHEET (sheet)) ; g_return_if_fail (range != NULL); - range->row0 = MIN_VISIBLE_ROW (sheet); - range->col0 = MIN_VISIBLE_COLUMN (sheet); - range->rowi = MAX_VISIBLE_ROW (sheet); - range->coli = MAX_VISIBLE_COLUMN (sheet); -} - -GtkAdjustment * -gtk_sheet_get_vadjustment (GtkSheet * sheet) -{ - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - - return sheet->vadjustment; + range->row0 = min_visible_row (sheet); + range->col0 = min_visible_column (sheet); + range->rowi = max_visible_row (sheet); + range->coli = max_visible_column (sheet); } -GtkAdjustment * -gtk_sheet_get_hadjustment (GtkSheet * sheet) -{ - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - - return sheet->hadjustment; -} -void -gtk_sheet_set_vadjustment (GtkSheet *sheet, - GtkAdjustment *adjustment) +static void +gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, + GtkAdjustment *hadjustment, + GtkAdjustment *vadjustment) { - GtkAdjustment *old_adjustment; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - if (adjustment) - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (sheet->vadjustment == adjustment) - return; - - old_adjustment = sheet->vadjustment; - - if (sheet->vadjustment) - { - g_signal_handlers_disconnect_matched (sheet->vadjustment, - G_SIGNAL_MATCH_DATA, - 0, 0, 0, 0, - sheet); - g_object_unref (sheet->vadjustment); - } - - sheet->vadjustment = adjustment; - - if (sheet->vadjustment) + if ( sheet->vadjustment != vadjustment ) { - g_object_ref (sheet->vadjustment); - g_object_ref_sink (sheet->vadjustment); + if (sheet->vadjustment) + g_object_unref (sheet->vadjustment); + sheet->vadjustment = vadjustment; + g_object_ref (vadjustment); g_signal_connect (sheet->vadjustment, "value_changed", G_CALLBACK (vadjustment_value_changed), sheet); } - if (!sheet->vadjustment || !old_adjustment) - { - gtk_widget_queue_resize (GTK_WIDGET (sheet)); - return; - } - - sheet->old_vadjustment = sheet->vadjustment->value; -} - -void -gtk_sheet_set_hadjustment (GtkSheet *sheet, - GtkAdjustment *adjustment) -{ - GtkAdjustment *old_adjustment; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - if (adjustment) - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (sheet->hadjustment == adjustment) - return; - - old_adjustment = sheet->hadjustment; - - if (sheet->hadjustment) - { - g_signal_handlers_disconnect_matched (sheet->hadjustment, - G_SIGNAL_MATCH_DATA, - 0, 0, 0, 0, - sheet); - g_object_unref (sheet->hadjustment); - } - - sheet->hadjustment = adjustment; - - if (sheet->hadjustment) + if ( sheet->hadjustment != hadjustment ) { - g_object_ref (sheet->hadjustment); - g_object_ref_sink (sheet->hadjustment); + if (sheet->hadjustment) + g_object_unref (sheet->hadjustment); + sheet->hadjustment = hadjustment; + g_object_ref (hadjustment); g_signal_connect (sheet->hadjustment, "value_changed", G_CALLBACK (hadjustment_value_changed), sheet); } - - if (!sheet->hadjustment || !old_adjustment) - { - gtk_widget_queue_resize (GTK_WIDGET (sheet)); - return; - } - - sheet->old_hadjustment = sheet->hadjustment->value; -} - -static void -gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment) -{ - if (sheet->hadjustment != hadjustment) - gtk_sheet_set_hadjustment (sheet, hadjustment); - - if (sheet->vadjustment != vadjustment) - gtk_sheet_set_vadjustment (sheet, vadjustment); } static void -gtk_sheet_finalize (GObject * object) +gtk_sheet_finalize (GObject *object) { GtkSheet *sheet; @@ -2430,7 +1647,6 @@ static void gtk_sheet_dispose (GObject *object) { GtkSheet *sheet = GTK_SHEET (object); - GList *children; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_SHEET (object)); @@ -2441,11 +1657,11 @@ gtk_sheet_dispose (GObject *object) sheet->dispose_has_run = TRUE; if (sheet->model) g_object_unref (sheet->model); - if (sheet->row_geometry) g_object_unref (sheet->row_geometry); - if (sheet->column_geometry) g_object_unref (sheet->column_geometry); + if (sheet->vaxis) g_object_unref (sheet->vaxis); + if (sheet->haxis) g_object_unref (sheet->haxis); - g_object_unref (sheet->entry_container); g_object_unref (sheet->button); + sheet->button = NULL; /* unref adjustments */ if (sheet->hadjustment) @@ -2471,16 +1687,6 @@ gtk_sheet_dispose (GObject *object) sheet->vadjustment = NULL; } - children = sheet->children; - while (children) - { - GtkSheetChild *child = (GtkSheetChild *)children->data; - if (child && child->widget) - gtk_sheet_remove (GTK_CONTAINER (sheet), child->widget); - children = sheet->children; - } - sheet->children = NULL; - if (G_OBJECT_CLASS (parent_class)->dispose) (*G_OBJECT_CLASS (parent_class)->dispose) (object); } @@ -2504,18 +1710,22 @@ gtk_sheet_style_set (GtkWidget *widget, gtk_style_set_background (widget->style, widget->window, widget->state); } + set_entry_widget_font (sheet); } +#define BORDER_WIDTH 2 + static void -gtk_sheet_realize (GtkWidget * widget) +gtk_sheet_realize (GtkWidget *widget) { GtkSheet *sheet; GdkWindowAttr attributes; - gint attributes_mask; - GdkGCValues values, auxvalues; + const gint attributes_mask = + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR; + + GdkGCValues values; GdkColormap *colormap; - GtkSheetChild *child; - GList *children; + GdkDisplay *display; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); @@ -2524,6 +1734,9 @@ gtk_sheet_realize (GtkWidget * widget) GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + colormap = gtk_widget_get_colormap (widget); + display = gtk_widget_get_display (widget); + attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; @@ -2532,19 +1745,19 @@ gtk_sheet_realize (GtkWidget * widget) attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); + attributes.colormap = colormap; attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | - GDK_WA_CURSOR; - attributes.cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); + attributes.cursor = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW); /* main window */ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); @@ -2555,39 +1768,47 @@ gtk_sheet_realize (GtkWidget * widget) gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + gdk_color_parse ("white", &sheet->color[BG_COLOR]); + gdk_colormap_alloc_color (colormap, &sheet->color[BG_COLOR], FALSE, + TRUE); + gdk_color_parse ("gray", &sheet->color[GRID_COLOR]); + gdk_colormap_alloc_color (colormap, &sheet->color[GRID_COLOR], FALSE, + TRUE); + attributes.x = 0; - if (sheet->row_titles_visible) - attributes.x = sheet->row_title_area.width; attributes.y = 0; attributes.width = sheet->column_title_area.width; attributes.height = sheet->column_title_area.height; + /* column - title window */ - sheet->column_title_window = gdk_window_new (widget->window, &attributes, attributes_mask); + sheet->column_title_window = + gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (sheet->column_title_window, sheet); - gtk_style_set_background (widget->style, sheet->column_title_window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, sheet->column_title_window, + GTK_STATE_NORMAL); + attributes.x = 0; attributes.y = 0; - if (sheet->column_titles_visible) - attributes.y = sheet->column_title_area.height; attributes.width = sheet->row_title_area.width; attributes.height = sheet->row_title_area.height; /* row - title window */ - sheet->row_title_window = gdk_window_new (widget->window, &attributes, attributes_mask); + sheet->row_title_window = gdk_window_new (widget->window, + &attributes, attributes_mask); gdk_window_set_user_data (sheet->row_title_window, sheet); - gtk_style_set_background (widget->style, sheet->row_title_window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, sheet->row_title_window, + GTK_STATE_NORMAL); /* sheet - window */ - attributes.cursor = gdk_cursor_new (GDK_PLUS); + attributes.cursor = gdk_cursor_new_for_display (display, GDK_PLUS); attributes.x = 0; attributes.y = 0; - attributes.width = sheet->sheet_window_width, - attributes.height = sheet->sheet_window_height; - sheet->sheet_window = gdk_window_new (widget->window, &attributes, attributes_mask); + sheet->sheet_window = gdk_window_new (widget->window, + &attributes, attributes_mask); gdk_window_set_user_data (sheet->sheet_window, sheet); gdk_cursor_unref (attributes.cursor); @@ -2595,31 +1816,22 @@ gtk_sheet_realize (GtkWidget * widget) gdk_window_set_background (sheet->sheet_window, &widget->style->white); gdk_window_show (sheet->sheet_window); - /* backing_pixmap */ - gtk_sheet_make_backing_pixmap (sheet, 0, 0); - /* GCs */ - if (sheet->fg_gc) - g_object_unref (sheet->fg_gc); - if (sheet->bg_gc) - g_object_unref (sheet->bg_gc); sheet->fg_gc = gdk_gc_new (widget->window); sheet->bg_gc = gdk_gc_new (widget->window); - colormap = gtk_widget_get_colormap (widget); - - gdk_gc_get_values (sheet->fg_gc, &auxvalues); - values.foreground = widget->style->white; values.function = GDK_INVERT; values.subwindow_mode = GDK_INCLUDE_INFERIORS; - if (sheet->xor_gc) - g_object_unref (sheet->xor_gc); + values.line_width = BORDER_WIDTH; + sheet->xor_gc = gdk_gc_new_with_values (widget->window, &values, GDK_GC_FOREGROUND | GDK_GC_FUNCTION | - GDK_GC_SUBWINDOW); + GDK_GC_SUBWINDOW | + GDK_GC_LINE_WIDTH + ); gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window); @@ -2629,25 +1841,17 @@ gtk_sheet_realize (GtkWidget * widget) gtk_widget_set_parent (sheet->button, GTK_WIDGET (sheet)); - gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_PLUS); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_PLUS); if (sheet->column_titles_visible) gdk_window_show (sheet->column_title_window); if (sheet->row_titles_visible) gdk_window_show (sheet->row_title_window); - size_allocate_row_title_buttons (sheet); - size_allocate_column_title_buttons (sheet); + sheet->hover_window = create_hover_window (); - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - gtk_sheet_realize_child (sheet, child); - } + draw_row_title_buttons (sheet); + draw_column_title_buttons (sheet); gtk_sheet_update_primary_selection (sheet); } @@ -2687,15 +1891,13 @@ size_allocate_global_button (GtkSheet *sheet) static void global_button_clicked (GtkWidget *widget, gpointer data) { - gboolean veto; - - gtk_sheet_click_cell (GTK_SHEET (data), - 1, - 1, &veto); + gtk_sheet_click_cell (GTK_SHEET (data), -1, -1); gtk_widget_grab_focus (GTK_WIDGET (data)); } static void -gtk_sheet_unrealize (GtkWidget * widget) +gtk_sheet_unrealize (GtkWidget *widget) { GtkSheet *sheet; @@ -2705,40 +1907,33 @@ gtk_sheet_unrealize (GtkWidget * widget) sheet = GTK_SHEET (widget); gdk_cursor_unref (sheet->cursor_drag); + sheet->cursor_drag = NULL; + + gdk_colormap_free_colors (gtk_widget_get_colormap (widget), + sheet->color, n_COLORS); g_object_unref (sheet->xor_gc); g_object_unref (sheet->fg_gc); g_object_unref (sheet->bg_gc); + destroy_hover_window (sheet->hover_window); + gdk_window_destroy (sheet->sheet_window); gdk_window_destroy (sheet->column_title_window); gdk_window_destroy (sheet->row_title_window); - if (sheet->pixmap) - { - g_object_unref (sheet->pixmap); - sheet->pixmap = NULL; - } - - sheet->column_title_window = NULL; - sheet->sheet_window = NULL; - sheet->xor_gc = NULL; - sheet->fg_gc = NULL; - sheet->bg_gc = NULL; - gtk_widget_unparent (sheet->entry_widget); - gtk_widget_unparent (sheet->button); + 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 -gtk_sheet_map (GtkWidget * widget) +gtk_sheet_map (GtkWidget *widget) { GtkSheet *sheet = GTK_SHEET (widget); - GtkSheetChild *child; - GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); @@ -2752,12 +1947,12 @@ gtk_sheet_map (GtkWidget * widget) if (sheet->column_titles_visible) { - size_allocate_column_title_buttons (sheet); + draw_column_title_buttons (sheet); gdk_window_show (sheet->column_title_window); } if (sheet->row_titles_visible) { - size_allocate_row_title_buttons (sheet); + draw_row_title_buttons (sheet); gdk_window_show (sheet->row_title_window); } @@ -2782,92 +1977,62 @@ gtk_sheet_map (GtkWidget * widget) gtk_widget_map (GTK_BIN (sheet->button)->child); gtk_sheet_range_draw (sheet, NULL); - gtk_sheet_activate_cell (sheet, - sheet->active_cell.row, - sheet->active_cell.col); - - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (child->widget) && - !GTK_WIDGET_MAPPED (child->widget)) - { - gtk_widget_map (child->widget); - gtk_sheet_position_child (sheet, child); - } - } - + change_active_cell (sheet, + sheet->active_cell.row, + sheet->active_cell.col); } } static void -gtk_sheet_unmap (GtkWidget * widget) +gtk_sheet_unmap (GtkWidget *widget) { - GtkSheet *sheet; - GtkSheetChild *child; - GList *children; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_SHEET (widget)); - - sheet = GTK_SHEET (widget); - - if (GTK_WIDGET_MAPPED (widget)) - { - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - - gdk_window_hide (sheet->sheet_window); - if (sheet->column_titles_visible) - gdk_window_hide (sheet->column_title_window); - if (sheet->row_titles_visible) - gdk_window_hide (sheet->row_title_window); - gdk_window_hide (widget->window); + GtkSheet *sheet = GTK_SHEET (widget); - if (GTK_WIDGET_MAPPED (sheet->entry_widget)) - gtk_widget_unmap (sheet->entry_widget); + if (!GTK_WIDGET_MAPPED (widget)) + return; - if (GTK_WIDGET_MAPPED (sheet->button)) - gtk_widget_unmap (sheet->button); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; + gdk_window_hide (sheet->sheet_window); + if (sheet->column_titles_visible) + gdk_window_hide (sheet->column_title_window); + if (sheet->row_titles_visible) + gdk_window_hide (sheet->row_title_window); + gdk_window_hide (widget->window); - if (GTK_WIDGET_VISIBLE (child->widget) && - GTK_WIDGET_MAPPED (child->widget)) - { - gtk_widget_unmap (child->widget); - } - } + if (GTK_WIDGET_MAPPED (sheet->entry_widget)) + gtk_widget_unmap (sheet->entry_widget); - } + if (GTK_WIDGET_MAPPED (sheet->button)) + gtk_widget_unmap (sheet->button); } static void -gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) +gtk_sheet_cell_draw (GtkSheet *sheet, gint row, gint col) { - GtkWidget *widget; - GdkGC *fg_gc, *bg_gc; + PangoLayout *layout; + PangoRectangle text; + PangoFontDescription *font_desc = GTK_WIDGET (sheet)->style->font_desc; + gint font_height; + + gchar *label; + GtkSheetCellAttr attributes; GdkRectangle area; g_return_if_fail (sheet != NULL); - /* bail now if we arn't drawable yet */ + /* bail now if we aren't yet drawable */ if (!GTK_WIDGET_DRAWABLE (sheet)) return; - if (row < 0 || row >= yyy_row_count (sheet)) return; - if (col < 0 || col >= xxx_column_count (sheet)) return; - if (! xxx_column_is_visible (sheet, col)) return; - if (! yyy_row_is_visible (sheet, row)) return; + if (row < 0 || + row >= psppire_axis_unit_count (sheet->vaxis)) + return; - widget = GTK_WIDGET (sheet); + if (col < 0 || + col >= psppire_axis_unit_count (sheet->haxis)) + return; gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -2875,226 +2040,79 @@ gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground); gdk_gc_set_foreground (sheet->bg_gc, &attributes.background); - fg_gc = sheet->fg_gc; - bg_gc = sheet->bg_gc; - - area.x = COLUMN_LEFT_XPIXEL (sheet, col); - area.y = ROW_TOP_YPIXEL (sheet, row); - area.width= xxx_column_width (sheet, col); - area.height = yyy_row_height (sheet, row); - - gdk_draw_rectangle (sheet->pixmap, - bg_gc, - TRUE, - area.x, - area.y, - area.width, - area.height); + rectangle_from_cell (sheet, row, col, &area); gdk_gc_set_line_attributes (sheet->fg_gc, 1, 0, 0, 0); if (sheet->show_grid) { - gdk_gc_set_foreground (sheet->bg_gc, &sheet->grid_color); + gdk_gc_set_foreground (sheet->bg_gc, &sheet->color[GRID_COLOR]); - gdk_draw_rectangle (sheet->pixmap, + gdk_draw_rectangle (sheet->sheet_window, sheet->bg_gc, FALSE, area.x, area.y, area.width, area.height); } -} - -static void -gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) -{ - GtkWidget *widget; - GdkRectangle area; - gint i; - gint text_width, text_height, y; - gint xoffset = 0; - gint size, sizel, sizer; - GdkGC *fg_gc, *bg_gc; - GtkSheetCellAttr attributes; - PangoLayout *layout; - PangoRectangle rect; - PangoRectangle logical_rect; - PangoLayoutLine *line; - PangoFontMetrics *metrics; - PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET (sheet)); - gint ascent, descent, y_pos; - - gchar *label; - g_return_if_fail (sheet != NULL); - - /* bail now if we aren't drawable yet */ - if (!GTK_WIDGET_DRAWABLE (sheet)) - return; label = gtk_sheet_cell_get_text (sheet, row, col); - if (!label) + if (NULL == label) return; - if (row < 0 || row >= yyy_row_count (sheet)) return; - if (col < 0 || col >= xxx_column_count (sheet)) return; - if (! xxx_column_is_visible (sheet, col)) return; - if (!yyy_row_is_visible (sheet, row)) return; - - - widget = GTK_WIDGET (sheet); - - gtk_sheet_get_attributes (sheet, row, col, &attributes); - - /* select GC for background rectangle */ - gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground); - gdk_gc_set_foreground (sheet->bg_gc, &attributes.background); - - fg_gc = sheet->fg_gc; - bg_gc = sheet->bg_gc; - - area.x = COLUMN_LEFT_XPIXEL (sheet, col); - area.y = ROW_TOP_YPIXEL (sheet, row); - area.width = xxx_column_width (sheet, col); - area.height = yyy_row_height (sheet, row); - layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), label); dispose_string (sheet, label); - pango_layout_set_font_description (layout, attributes.font_desc); - - pango_layout_get_pixel_extents (layout, NULL, &rect); - - line = pango_layout_get_lines (layout)->data; - pango_layout_line_get_extents (line, NULL, &logical_rect); - metrics = pango_context_get_metrics (context, - attributes.font_desc, - pango_context_get_language (context)); - ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE; - descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE; + pango_layout_set_font_description (layout, font_desc); - pango_font_metrics_unref (metrics); + pango_layout_get_pixel_extents (layout, NULL, &text); - /* Align primarily for locale's ascent / descent */ + gdk_gc_set_clip_rectangle (sheet->fg_gc, &area); - logical_rect.height /= PANGO_SCALE; - logical_rect.y /= PANGO_SCALE; - y_pos = area.height - logical_rect.height; + font_height = pango_font_description_get_size (font_desc); + if ( !pango_font_description_get_size_is_absolute (font_desc)) + font_height /= PANGO_SCALE; - if (logical_rect.height > area.height) - y_pos = (logical_rect.height - area.height - 2 * CELLOFFSET) / 2; - else if (y_pos < 0) - y_pos = 0; - else if (y_pos + logical_rect.height > area.height) - y_pos = area.height - logical_rect.height; - - text_width = rect.width; - text_height = rect.height; - y = area.y + y_pos - CELLOFFSET; + /* Centre the text vertically */ + area.y += (area.height - font_height) / 2.0; switch (attributes.justification) { case GTK_JUSTIFY_RIGHT: - size = area.width; - area.x +=area.width; - { - for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--) - { - if ( !gtk_sheet_cell_empty (sheet, row, i)) break; - if (size >= text_width + CELLOFFSET) break; - size +=xxx_column_width (sheet, i); - xxx_column_set_right_column (sheet, i, - MAX (col, - xxx_column_right_column (sheet, i))); - } - area.width = size; - } - area.x -= size; - xoffset += area.width - text_width - 2 * CELLOFFSET - - attributes.border.width / 2; + area.x += area.width - text.width; break; case GTK_JUSTIFY_CENTER: - sizel = area.width / 2; - sizer = area.width / 2; - area.x += area.width / 2; - { - for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++) - { - if ( ! gtk_sheet_cell_empty (sheet, row, i)) break; - if (sizer >= text_width / 2) break; - sizer += xxx_column_width (sheet, i); - xxx_column_set_left_column (sheet, i, - MIN ( - col, - xxx_column_left_column (sheet, i))); - } - for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--) - { - if ( ! gtk_sheet_cell_empty (sheet, row, i)) break; - if (sizel >= text_width / 2) break; - sizel +=xxx_column_width (sheet, i); - xxx_column_set_right_column (sheet, i, - MAX (col, - xxx_column_right_column (sheet, i))); - } - size = MIN (sizel, sizer); - } - area.x -= sizel; - xoffset += sizel - text_width / 2 - CELLOFFSET; - area.width = sizel + sizer; + area.x += (area.width - text.width) / 2.0; break; case GTK_JUSTIFY_LEFT: + /* Do nothing */ + break; default: - size = area.width; - { - for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++) - { - if (! gtk_sheet_cell_empty (sheet, row, i)) break; - if (size >= text_width + CELLOFFSET) break; - size +=xxx_column_width (sheet, i); - xxx_column_set_left_column (sheet, i, - MIN ( - col, - xxx_column_left_column (sheet, i))); - - } - area.width = size; - } - xoffset += attributes.border.width / 2; + g_critical ("Unhandled justification %d in column %d\n", + attributes.justification, col); break; } - gdk_gc_set_clip_rectangle (fg_gc, &area); - - - gdk_draw_layout (sheet->pixmap, fg_gc, - area.x + xoffset + CELLOFFSET, - y, + gdk_draw_layout (sheet->sheet_window, sheet->fg_gc, + area.x, + area.y, layout); - gdk_gc_set_clip_rectangle (fg_gc, NULL); + gdk_gc_set_clip_rectangle (sheet->fg_gc, NULL); g_object_unref (layout); +} - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - area.x, - area.y, - area.x, - area.y, - area.width, - area.height); -} static void gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) { gint i, j; - GtkSheetRange drawing_range; + GdkRectangle area; + GtkSheetRange drawing_range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_SHEET (sheet)); @@ -3105,94 +2123,41 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) if (range == NULL) { - drawing_range.row0 = MIN_VISIBLE_ROW (sheet); - drawing_range.col0 = MIN_VISIBLE_COLUMN (sheet); - drawing_range.rowi = MIN (MAX_VISIBLE_ROW (sheet), - yyy_row_count (sheet) - 1); - drawing_range.coli = MAX_VISIBLE_COLUMN (sheet); - - - gdk_draw_rectangle (sheet->pixmap, - GTK_WIDGET (sheet)->style->white_gc, - TRUE, - 0, 0, - sheet->sheet_window_width, - sheet->sheet_window_height); + drawing_range.row0 = min_visible_row (sheet); + drawing_range.col0 = min_visible_column (sheet); + drawing_range.rowi = MIN (max_visible_row (sheet), + psppire_axis_unit_count (sheet->vaxis) - 1); + drawing_range.coli = max_visible_column (sheet); + gdk_drawable_get_size (sheet->sheet_window, &area.width, &area.height); + area.x = area.y = 0; } else { - drawing_range.row0 = MAX (range->row0, MIN_VISIBLE_ROW (sheet)); - drawing_range.col0 = MAX (range->col0, MIN_VISIBLE_COLUMN (sheet)); - drawing_range.rowi = MIN (range->rowi, MAX_VISIBLE_ROW (sheet)); - drawing_range.coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet)); - } - - if (drawing_range.coli == xxx_column_count (sheet) - 1) - { - area.x = COLUMN_LEFT_XPIXEL (sheet, - xxx_column_count (sheet) - 1) + - xxx_column_width (sheet, xxx_column_count (sheet) - 1) + 1; + 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)); - area.y = 0; - - gdk_gc_set_foreground (sheet->fg_gc, &sheet->bg_color); - - gdk_draw_rectangle (sheet->pixmap, - sheet->fg_gc, - TRUE, - area.x, area.y, - sheet->sheet_window_width - area.x, - sheet->sheet_window_height); - - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - area.x, - area.y, - area.x, - area.y, - sheet->sheet_window_width - area.x, - sheet->sheet_window_height); + rectangle_from_range (sheet, &drawing_range, &area); } - if (drawing_range.rowi == yyy_row_count (sheet) - 1) - { - area.x = 0; - area.y = ROW_TOP_YPIXEL (sheet, - yyy_row_count (sheet) - 1) + - yyy_row_height (sheet, yyy_row_count (sheet) - 1) + 1; + g_return_if_fail (drawing_range.rowi >= drawing_range.row0); + g_return_if_fail (drawing_range.coli >= drawing_range.col0); - gdk_gc_set_foreground (sheet->fg_gc, &sheet->bg_color); - - gdk_draw_rectangle (sheet->pixmap, - sheet->fg_gc, - TRUE, - area.x, area.y, - sheet->sheet_window_width, - sheet->sheet_window_height - area.y); - - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - area.x, - area.y, - area.x, - area.y, - sheet->sheet_window_width, - sheet->sheet_window_height - area.y); - } + gdk_draw_rectangle (sheet->sheet_window, + GTK_WIDGET (sheet)->style->white_gc, + TRUE, + area.x, area.y, + area.width, area.height); for (i = drawing_range.row0; i <= drawing_range.rowi; i++) for (j = drawing_range.col0; j <= drawing_range.coli; j++) { - gtk_sheet_cell_draw_default (sheet, i, j); - gtk_sheet_cell_draw_label (sheet, i, j); + gtk_sheet_cell_draw (sheet, i, j); } - gtk_sheet_draw_backing_pixmap (sheet, drawing_range); - if (sheet->state != GTK_SHEET_NORMAL && - gtk_sheet_range_isvisible (sheet, sheet->range)) + gtk_sheet_range_isvisible (sheet, &sheet->range)) gtk_sheet_range_draw_selection (sheet, drawing_range); if (sheet->state == GTK_STATE_NORMAL && @@ -3200,7 +2165,7 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) sheet->active_cell.row <= drawing_range.rowi && sheet->active_cell.col >= drawing_range.col0 && sheet->active_cell.col <= drawing_range.coli) - gtk_sheet_show_active_cell (sheet); + gtk_sheet_show_entry_widget (sheet); } static void @@ -3214,7 +2179,7 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) range.row0 > sheet->range.rowi || range.rowi < sheet->range.row0) return; - if (!gtk_sheet_range_isvisible (sheet, range)) return; + if (!gtk_sheet_range_isvisible (sheet, &range)) return; if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; aux = range; @@ -3224,24 +2189,18 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) range.row0 = MAX (sheet->range.row0, range.row0); range.rowi = MIN (sheet->range.rowi, range.rowi); - range.col0 = MAX (range.col0, MIN_VISIBLE_COLUMN (sheet)); - range.coli = MIN (range.coli, MAX_VISIBLE_COLUMN (sheet)); - range.row0 = MAX (range.row0, MIN_VISIBLE_ROW (sheet)); - range.rowi = MIN (range.rowi, MAX_VISIBLE_ROW (sheet)); + range.col0 = MAX (range.col0, min_visible_column (sheet)); + range.coli = MIN (range.coli, max_visible_column (sheet)); + range.row0 = MAX (range.row0, min_visible_row (sheet)); + range.rowi = MIN (range.rowi, max_visible_row (sheet)); for (i = range.row0; i <= range.rowi; i++) { for (j = range.col0; j <= range.coli; j++) { - - if (gtk_sheet_cell_get_state (sheet, i, j) == GTK_STATE_SELECTED && - xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i)) + if (gtk_sheet_cell_get_state (sheet, i, j) == GTK_STATE_SELECTED) { - - area.x = COLUMN_LEFT_XPIXEL (sheet, j); - area.y = ROW_TOP_YPIXEL (sheet, i); - area.width= xxx_column_width (sheet, j); - area.height = yyy_row_height (sheet, i); + rectangle_from_cell (sheet, i, j, &area); if (i == sheet->range.row0) { @@ -3272,153 +2231,41 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) gtk_sheet_draw_border (sheet, sheet->range); } -static void -gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, GtkSheetRange range) -{ - gint x, y, width, height; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - - x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - y = ROW_TOP_YPIXEL (sheet, range.row0); - width = COLUMN_LEFT_XPIXEL (sheet, range.coli) - x + - xxx_column_width (sheet, range.coli); - - height = ROW_TOP_YPIXEL (sheet, range.rowi)- y + yyy_row_height (sheet, range.rowi); - - if (range.row0 == sheet->range.row0) - { - y = y - 5; - height = height + 5; - } - if (range.rowi == sheet->range.rowi) height = height + 5; - if (range.col0 == sheet->range.col0) - { - x = x - 5; - width = width + 5; - } - if (range.coli == sheet->range.coli) width = width + 5; - - width = MIN (width, sheet->sheet_window_width - x); - height = MIN (height, sheet->sheet_window_height - y); - - x--; - y--; - width +=2; - height +=2; - - x = (sheet->row_titles_visible) - ? MAX (x, sheet->row_title_area.width) : MAX (x, 0); - y = (sheet->column_titles_visible) - ? MAX (y, sheet->column_title_area.height) : MAX (y, 0); - - if (range.coli == xxx_column_count (sheet) - 1) - width = sheet->sheet_window_width - x; - if (range.rowi == yyy_row_count (sheet) - 1) - height = sheet->sheet_window_height - y; - - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x, - y, - x, - y, - width + 1, - height + 1); -} - - -void -gtk_sheet_set_cell_text (GtkSheet *sheet, gint row, gint col, const gchar *text) -{ - GtkSheetCellAttr attributes; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return; - if (col < 0 || row < 0) return; - - gtk_sheet_get_attributes (sheet, row, col, &attributes); - gtk_sheet_set_cell (sheet, row, col, attributes.justification, text); -} - static inline gint safe_strcmp (const gchar *s1, const gchar *s2) { if ( !s1 && !s2) return 0; - if ( !s1) return - 1; + if ( !s1) return -1; if ( !s2) return +1; return strcmp (s1, s2); } -void +static void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, GtkJustification justification, const gchar *text) { - GSheetModel *model ; - gboolean changed ; - gchar *old_text ; - - GtkSheetRange range; - gint text_width; - GtkSheetCellAttr attributes; + GSheetModel *model ; + gchar *old_text ; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return; - if (col < 0 || row < 0) return; - gtk_sheet_get_attributes (sheet, row, col, &attributes); + if (col >= psppire_axis_unit_count (sheet->haxis) + || row >= psppire_axis_unit_count (sheet->vaxis)) + return; - attributes.justification = justification; + if (col < 0 || row < 0) return; model = gtk_sheet_get_model (sheet); old_text = g_sheet_model_get_string (model, row, col); - changed = FALSE; - if (0 != safe_strcmp (old_text, text)) - changed = g_sheet_model_set_string (model, text, row, col); + g_sheet_model_set_string (model, text, row, col); if ( g_sheet_model_free_strings (model)) g_free (old_text); - - - if (changed && attributes.is_visible) - { - gchar *s = gtk_sheet_cell_get_text (sheet, row, col); - text_width = 0; - if (s && strlen (s) > 0) - { - text_width = STRING_WIDTH (GTK_WIDGET (sheet), - attributes.font_desc, text); - } - dispose_string (sheet, s); - - range.row0 = row; - range.rowi = row; - range.col0 = MIN_VISIBLE_COLUMN (sheet); - range.coli = MAX_VISIBLE_COLUMN (sheet); - - if (gtk_sheet_autoresize (sheet) && - text_width > xxx_column_width (sheet, col) - - 2 * CELLOFFSET- attributes.border.width) - { - gtk_sheet_set_column_width (sheet, col, text_width + 2 * CELLOFFSET - + attributes.border.width); - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING); - } - else - if (!GTK_SHEET_IS_FROZEN (sheet)) - gtk_sheet_range_draw (sheet, &range); - } - - if ( changed ) - g_signal_emit (sheet, sheet_signals[CHANGED], 0, row, col); - } @@ -3429,22 +2276,19 @@ gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint column) g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column >= xxx_column_count (sheet) || - row >= yyy_row_count (sheet)) return; + if (column >= psppire_axis_unit_count (sheet->haxis) || + row >= psppire_axis_unit_count (sheet->vaxis)) return; if (column < 0 || row < 0) return; range.row0 = row; range.rowi = row; - range.col0 = MIN_VISIBLE_COLUMN (sheet); - range.coli = MAX_VISIBLE_COLUMN (sheet); + range.col0 = min_visible_column (sheet); + range.coli = max_visible_column (sheet); gtk_sheet_real_cell_clear (sheet, row, column); - if (!GTK_SHEET_IS_FROZEN (sheet)) - { - gtk_sheet_range_draw (sheet, &range); - } + gtk_sheet_range_draw (sheet, &range); } static void @@ -3462,59 +2306,6 @@ gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column) dispose_string (sheet, old_text); } -void -gtk_sheet_range_clear (GtkSheet *sheet, const GtkSheetRange *range) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - gtk_sheet_real_range_clear (sheet, range); -} - -static void -gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range) -{ - gint i, j; - GtkSheetRange clear; - - if (!range) - { - clear.row0 = 0; - clear.rowi = yyy_row_count (sheet) - 1; - clear.col0 = 0; - clear.coli = xxx_column_count (sheet) - 1; - } - else - clear=*range; - - clear.row0 = MAX (clear.row0, 0); - clear.col0 = MAX (clear.col0, 0); - clear.rowi = MIN (clear.rowi, yyy_row_count (sheet) - 1 ); - clear.coli = MIN (clear.coli, xxx_column_count (sheet) - 1 ); - - for (i = clear.row0; i <= clear.rowi; i++) - for (j = clear.col0; j <= clear.coli; j++) - { - gtk_sheet_real_cell_clear (sheet, i, j); - } - - gtk_sheet_range_draw (sheet, NULL); -} - - -static gboolean -gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col) -{ - gboolean empty; - char *text = gtk_sheet_cell_get_text (sheet, row, col); - empty = (text == NULL ); - - dispose_string (sheet, text); - - return empty; -} - - gchar * gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col) { @@ -3522,7 +2313,7 @@ gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col) g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) + if (col >= psppire_axis_unit_count (sheet->haxis) || row >= psppire_axis_unit_count (sheet->vaxis)) return NULL; if (col < 0 || row < 0) return NULL; @@ -3535,7 +2326,7 @@ gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col) } -GtkStateType +static GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) { gint state; @@ -3543,7 +2334,7 @@ gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - if (col >= xxx_column_count (sheet) || row >= yyy_row_count (sheet)) return 0; + if (col >= psppire_axis_unit_count (sheet->haxis) || row >= psppire_axis_unit_count (sheet->vaxis)) return 0; if (col < 0 || row < 0) return 0; state = sheet->state; @@ -3571,11 +2362,10 @@ gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) return GTK_STATE_NORMAL; } -/* Convert X, Y (in pixels) to *ROW, *COLUMN (in cell coords) - -1 indicates the title buttons. +/* Convert X, Y (in pixels) to *ROW, *COLUMN If the function returns FALSE, then the results will be unreliable. */ -gboolean +static gboolean gtk_sheet_get_pixel_info (GtkSheet *sheet, gint x, gint y, @@ -3597,34 +2387,47 @@ gtk_sheet_get_pixel_info (GtkSheet *sheet, if (x < 0) return FALSE; - if ( y < sheet->column_title_area.height + sheet->column_title_area.y) - *row = -1; + if ( sheet->column_titles_visible) + y -= sheet->column_title_area.height; + + y += sheet->vadjustment->value; + if ( y < 0 && sheet->column_titles_visible) + { + trow = -1; + } else { - trow = ROW_FROM_YPIXEL (sheet, y); - if (trow > yyy_row_count (sheet)) + trow = row_from_ypixel (sheet, y); + if (trow > psppire_axis_unit_count (sheet->vaxis)) return FALSE; - - *row = trow; } - if ( x < sheet->row_title_area.width + sheet->row_title_area.x) - *column = -1; + *row = trow; + + if ( sheet->row_titles_visible) + x -= sheet->row_title_area.width; + + x += sheet->hadjustment->value; + + if ( x < 0 && sheet->row_titles_visible) + { + tcol = -1; + } else { - tcol = COLUMN_FROM_XPIXEL (sheet, x); - if (tcol > xxx_column_count (sheet)) + tcol = column_from_xpixel (sheet, x); + if (tcol > psppire_axis_unit_count (sheet->haxis)) return FALSE; - - *column = tcol; } + *column = tcol; + return TRUE; } gboolean -gtk_sheet_get_cell_area (GtkSheet * sheet, +gtk_sheet_get_cell_area (GtkSheet *sheet, gint row, gint column, GdkRectangle *area) @@ -3632,54 +2435,48 @@ gtk_sheet_get_cell_area (GtkSheet * sheet, g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet)) + if (row >= psppire_axis_unit_count (sheet->vaxis) || column >= psppire_axis_unit_count (sheet->haxis)) return FALSE; - area->x = (column == -1) ? 0 : (COLUMN_LEFT_XPIXEL (sheet, column) - - (sheet->row_titles_visible - ? sheet->row_title_area.width - : 0)); - area->y = (row == -1) ? 0 : (ROW_TOP_YPIXEL (sheet, row) - - (sheet->column_titles_visible - ? sheet->column_title_area.height - : 0)); + area->x = (column == -1) ? 0 : psppire_axis_pixel_start (sheet->haxis, column); + area->y = (row == -1) ? 0 : psppire_axis_pixel_start (sheet->vaxis, row); + area->width= (column == -1) ? sheet->row_title_area.width - : xxx_column_width (sheet, column); + : psppire_axis_unit_size (sheet->haxis, column); area->height= (row == -1) ? sheet->column_title_area.height - : yyy_row_height (sheet, row); + : psppire_axis_unit_size (sheet->vaxis, row); return TRUE; } -gboolean -gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column) +void +gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint col) { - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); + g_return_if_fail (sheet != NULL); + g_return_if_fail (GTK_IS_SHEET (sheet)); - if (row < - 1 || column < - 1) return FALSE; - if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet)) - return FALSE; + if (row < -1 || col < -1) + return; - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - gtk_sheet_deactivate_cell (sheet); + if (row >= psppire_axis_unit_count (sheet->vaxis) + || + col >= psppire_axis_unit_count (sheet->haxis)) + return; sheet->active_cell.row = row; - sheet->active_cell.col = column; + sheet->active_cell.col = col; + + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + return; - if ( row == -1 || column == -1) + if ( row == -1 || col == -1) { - gtk_sheet_hide_active_cell (sheet); - return TRUE; + gtk_sheet_hide_entry_widget (sheet); + return; } - if (!gtk_sheet_activate_cell (sheet, row, column)) return FALSE; - - if (gtk_sheet_autoscroll (sheet)) - gtk_sheet_move_query (sheet, row, column); - - return TRUE; + change_active_cell (sheet, row, col); } void @@ -3717,9 +2514,7 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data) sheet->active_cell.row = -1; sheet->active_cell.col = -1; - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); - - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); + text = gtk_entry_get_text (gtk_sheet_get_entry (sheet)); if (text && strlen (text) > 0) { @@ -3728,112 +2523,71 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data) gtk_sheet_set_cell (sheet, row, col, justification, text); } - if (sheet->freeze_count == 0) - GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); - sheet->active_cell.row = row;; sheet->active_cell.col = col; } static void -gtk_sheet_deactivate_cell (GtkSheet *sheet) -{ - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return ; - if (sheet->state != GTK_SHEET_NORMAL) return ; - - if ( sheet->active_cell.row == -1 || sheet->active_cell.col == -1 ) - return ; - - g_signal_emit (sheet, sheet_signals[DEACTIVATE], 0, - sheet->active_cell.row, - sheet->active_cell.col); - - - g_signal_handlers_disconnect_by_func (gtk_sheet_get_entry (sheet), - G_CALLBACK (gtk_sheet_entry_changed), - sheet); - - gtk_sheet_hide_active_cell (sheet); - sheet->active_cell.row = -1; - sheet->active_cell.col = -1; - - if (GTK_SHEET_REDRAW_PENDING (sheet)) - { - GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING); - gtk_sheet_range_draw (sheet, NULL); - } -} - -static void -gtk_sheet_hide_active_cell (GtkSheet *sheet) +gtk_sheet_hide_entry_widget (GtkSheet *sheet) { - const char *text; - gint row, col; - GtkJustification justification; - GtkSheetCellAttr attributes; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - - row = sheet->active_cell.row; - col = sheet->active_cell.col; - - if (row < 0 || col < 0) return; - - if (sheet->freeze_count == 0) - GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); - - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); - - gtk_sheet_get_attributes (sheet, row, col, &attributes); - justification = attributes.justification; + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + return; - row = sheet->active_cell.row; - col = sheet->active_cell.col; + if (sheet->active_cell.row < 0 || + sheet->active_cell.col < 0) return; gtk_widget_hide (sheet->entry_widget); gtk_widget_unmap (sheet->entry_widget); - if (row != -1 && col != -1) - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - COLUMN_LEFT_XPIXEL (sheet, col)- 1, - ROW_TOP_YPIXEL (sheet, row)- 1, - COLUMN_LEFT_XPIXEL (sheet, col)- 1, - ROW_TOP_YPIXEL (sheet, row)- 1, - xxx_column_width (sheet, col) + 4, - yyy_row_height (sheet, row)+4); - - gtk_widget_grab_focus (GTK_WIDGET (sheet)); - GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE); - } -static gboolean -gtk_sheet_activate_cell (GtkSheet *sheet, gint row, gint col) +static void +change_active_cell (GtkSheet *sheet, gint row, gint col) { - gboolean veto = TRUE; + gint old_row, old_col; + glong old_handler_id = sheet->entry_handler_id; - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); + g_return_if_fail (GTK_IS_SHEET (sheet)); - if (row < 0 || col < 0) return FALSE; + if (row < 0 || col < 0) + return; - if ( row > yyy_row_count (sheet) || col > xxx_column_count (sheet)) - return FALSE; + if ( row > psppire_axis_unit_count (sheet->vaxis) + || col > psppire_axis_unit_count (sheet->haxis)) + return; - if (!veto) return FALSE; if (sheet->state != GTK_SHEET_NORMAL) { sheet->state = GTK_SHEET_NORMAL; gtk_sheet_real_unselect_range (sheet, NULL); } + + g_signal_handler_block (sheet->entry_widget, sheet->entry_handler_id); + + old_row = sheet->active_cell.row; + old_col = sheet->active_cell.col; + + { + /* Redraw the neighbourhood of the old active cell */ + GtkSheetRange r; + r.col0 = old_col - 1; + r.coli = old_col + 1; + r.row0 = old_row - 1; + r.rowi = old_row + 1; + + maximize_int (&r.row0, 0); + maximize_int (&r.col0, 0); + minimize_int (&r.rowi, psppire_axis_unit_count (sheet->vaxis) - 1); + minimize_int (&r.coli, psppire_axis_unit_count (sheet->haxis) - 1); + + + if ( gtk_sheet_range_isvisible (sheet, &r)) + gtk_sheet_range_draw (sheet, &r); + } + sheet->range.row0 = row; sheet->range.col0 = col; sheet->range.rowi = row; @@ -3845,26 +2599,23 @@ gtk_sheet_activate_cell (GtkSheet *sheet, gint row, gint col) GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); - gtk_sheet_show_active_cell (sheet); + gtk_sheet_draw_active_cell (sheet); + gtk_sheet_show_entry_widget (sheet); - g_signal_connect (gtk_sheet_get_entry (sheet), - "changed", - G_CALLBACK (gtk_sheet_entry_changed), - sheet); - _gtkextra_signal_emit (GTK_OBJECT (sheet), sheet_signals [ACTIVATE], row, col, &veto); + g_signal_emit (sheet, sheet_signals [ACTIVATE], 0, + row, col, old_row, old_col); - return TRUE; + if ( old_handler_id == sheet->entry_handler_id) + g_signal_handler_unblock (sheet->entry_widget, sheet->entry_handler_id); } static void -gtk_sheet_show_active_cell (GtkSheet *sheet) +gtk_sheet_show_entry_widget (GtkSheet *sheet) { GtkEntry *sheet_entry; GtkSheetCellAttr attributes; gchar *text = NULL; - const gchar *old_text; - GtkJustification justification; gint row, col; g_return_if_fail (sheet != NULL); @@ -3883,35 +2634,41 @@ gtk_sheet_show_active_cell (GtkSheet *sheet) GTK_WIDGET_SET_FLAGS (GTK_WIDGET (sheet->entry_widget), GTK_VISIBLE); - sheet_entry = GTK_ENTRY (gtk_sheet_get_entry (sheet)); + sheet_entry = gtk_sheet_get_entry (sheet); gtk_sheet_get_attributes (sheet, row, col, &attributes); - justification = GTK_JUSTIFY_LEFT; - - if (gtk_sheet_justify_entry (sheet)) - justification = attributes.justification; text = gtk_sheet_cell_get_text (sheet, row, col); if ( ! text ) text = g_strdup (""); - gtk_entry_set_visibility (GTK_ENTRY (sheet_entry), attributes.is_visible); - - - /*** Added by John Gotts. Mar 25, 2005 *********/ - old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry)); - if (strcmp (old_text, text) != 0) + if ( GTK_IS_ENTRY (sheet_entry)) { - if (!GTK_IS_ITEM_ENTRY (sheet_entry)) - gtk_entry_set_text (GTK_ENTRY (sheet_entry), text); - else - gtk_item_entry_set_text (GTK_ITEM_ENTRY (sheet_entry), text, justification); + const gchar *old_text = gtk_entry_get_text (GTK_ENTRY (sheet_entry)); + if (strcmp (old_text, text) != 0) + gtk_entry_set_text (sheet_entry, text); + + switch (attributes.justification) + { + case GTK_JUSTIFY_RIGHT: + gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 1.0); + break; + case GTK_JUSTIFY_CENTER: + gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.5); + break; + case GTK_JUSTIFY_LEFT: + default: + gtk_entry_set_alignment (GTK_ENTRY (sheet_entry), 0.0); + break; + } } - gtk_sheet_entry_set_max_size (sheet); gtk_sheet_size_allocate_entry (sheet); + gtk_widget_set_sensitive (GTK_WIDGET (sheet_entry), + g_sheet_model_is_editable (sheet->model, + row, col)); gtk_widget_map (sheet->entry_widget); gtk_widget_grab_focus (GTK_WIDGET (sheet_entry)); @@ -3933,7 +2690,8 @@ gtk_sheet_draw_active_cell (GtkSheet *sheet) if (row < 0 || col < 0) return; - if (!gtk_sheet_cell_isvisible (sheet, row, col)) return; + if (!gtk_sheet_cell_isvisible (sheet, row, col)) + return; range.col0 = range.coli = col; range.row0 = range.rowi = row; @@ -3942,42 +2700,6 @@ gtk_sheet_draw_active_cell (GtkSheet *sheet) } -static void -gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height) -{ - gint pixmap_width, pixmap_height; - - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - - if (width == 0 && height == 0) - { - width = sheet->sheet_window_width + 80; - height = sheet->sheet_window_height + 80; - } - - if (!sheet->pixmap) - { - /* allocate */ - sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, - width, height, - - 1); - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); - } - else - { - /* reallocate if sizes don't match */ - gdk_drawable_get_size (sheet->pixmap, - &pixmap_width, &pixmap_height); - if ( (pixmap_width != width) || (pixmap_height != height)) - { - g_object_unref (sheet->pixmap); - sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, - width, height, - - 1); - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); - } - } -} static void gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) @@ -3998,15 +2720,15 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) range->col0 = MIN (range->col0, sheet->range.col0); range->coli = MAX (range->coli, sheet->range.coli); - range->row0 = MAX (range->row0, MIN_VISIBLE_ROW (sheet)); - range->rowi = MIN (range->rowi, MAX_VISIBLE_ROW (sheet)); - range->col0 = MAX (range->col0, MIN_VISIBLE_COLUMN (sheet)); - range->coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet)); + range->row0 = MAX (range->row0, min_visible_row (sheet)); + range->rowi = MIN (range->rowi, max_visible_row (sheet)); + range->col0 = MAX (range->col0, min_visible_column (sheet)); + range->coli = MIN (range->coli, max_visible_column (sheet)); - aux_range.row0 = MAX (new_range.row0, MIN_VISIBLE_ROW (sheet)); - aux_range.rowi = MIN (new_range.rowi, MAX_VISIBLE_ROW (sheet)); - aux_range.col0 = MAX (new_range.col0, MIN_VISIBLE_COLUMN (sheet)); - aux_range.coli = MIN (new_range.coli, MAX_VISIBLE_COLUMN (sheet)); + aux_range.row0 = MAX (new_range.row0, min_visible_row (sheet)); + aux_range.rowi = MIN (new_range.rowi, max_visible_row (sheet)); + aux_range.col0 = MAX (new_range.col0, min_visible_column (sheet)); + aux_range.coli = MIN (new_range.coli, max_visible_column (sheet)); for (i = range->row0; i <= range->rowi; i++) { @@ -4018,7 +2740,6 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE; if (state == GTK_STATE_SELECTED && selected && - xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i) && (i == sheet->range.row0 || i == sheet->range.rowi || j == sheet->range.col0 || j == sheet->range.coli || i == new_range.row0 || i == new_range.rowi || @@ -4037,11 +2758,11 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (mask1 != mask2) { - x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); - width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ - xxx_column_width (sheet, j); - height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i); + x = psppire_axis_pixel_start (sheet->haxis, j); + y = psppire_axis_pixel_start (sheet->vaxis, i); + width = psppire_axis_pixel_start (sheet->haxis, j)- x+ + psppire_axis_unit_size (sheet->haxis, j); + height = psppire_axis_pixel_start (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i); if (i == sheet->range.row0) { @@ -4056,24 +2777,14 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) } if (j == sheet->range.coli) width = width + 3; - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x + 1, - y + 1, - x + 1, - y + 1, - width, - height); - if (i != sheet->active_cell.row || j != sheet->active_cell.col) { - x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); - width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ - xxx_column_width (sheet, j); + x = psppire_axis_pixel_start (sheet->haxis, j); + y = psppire_axis_pixel_start (sheet->vaxis, i); + width = psppire_axis_pixel_start (sheet->haxis, j)- x+ + psppire_axis_unit_size (sheet->haxis, j); - height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i); + height = psppire_axis_pixel_start (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i); if (i == new_range.row0) { @@ -4108,14 +2819,13 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) selected= (i <= new_range.rowi && i >= new_range.row0 && j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE; - if (state == GTK_STATE_SELECTED && !selected && - xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i)) + if (state == GTK_STATE_SELECTED && !selected) { - x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); - width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ xxx_column_width (sheet, j); - height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i); + x = psppire_axis_pixel_start (sheet->haxis, j); + y = psppire_axis_pixel_start (sheet->vaxis, i); + width = psppire_axis_pixel_start (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j); + height = psppire_axis_pixel_start (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i); if (i == sheet->range.row0) { @@ -4130,15 +2840,6 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) } if (j == sheet->range.coli) width = width + 3; - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x + 1, - y + 1, - x + 1, - y + 1, - width, - height); } } } @@ -4153,14 +2854,13 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE; if (state != GTK_STATE_SELECTED && selected && - xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i) && (i != sheet->active_cell.row || j != sheet->active_cell.col)) { - x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); - width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ xxx_column_width (sheet, j); - height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i); + x = psppire_axis_pixel_start (sheet->haxis, j); + y = psppire_axis_pixel_start (sheet->vaxis, i); + width = psppire_axis_pixel_start (sheet->haxis, j) - x + psppire_axis_unit_size (sheet->haxis, j); + height = psppire_axis_pixel_start (sheet->vaxis, i) - y + psppire_axis_unit_size (sheet->vaxis, i); if (i == new_range.row0) { @@ -4171,258 +2871,100 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (j == new_range.col0) { x = x+2; - width = width - 2; - } - if (j == new_range.coli) width = width - 3; - - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x + 1, y + 1, - width, height); - - } - - } - } - - for (i = aux_range.row0; i <= aux_range.rowi; i++) - { - for (j = aux_range.col0; j <= aux_range.coli; j++) - { - - if (xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i)) - { - - state = gtk_sheet_cell_get_state (sheet, i, j); - - mask1 = i == sheet->range.row0 ? 1 : 0; - mask1 = i == sheet->range.rowi ? mask1 + 2 : mask1; - mask1 = j == sheet->range.col0 ? mask1 + 4 : mask1; - mask1 = j == sheet->range.coli ? mask1 + 8 : mask1; - - mask2 = i == new_range.row0 ? 1 : 0; - mask2 = i == new_range.rowi ? mask2 + 2 : mask2; - mask2 = j == new_range.col0 ? mask2 + 4 : mask2; - mask2 = j == new_range.coli ? mask2 + 8 : mask2; - if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED)) - { - x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); - width = xxx_column_width (sheet, j); - height = yyy_row_height (sheet, i); - if (mask2 & 1) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x + 1, y - 1, - width, 3); - - - if (mask2 & 2) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x + 1, y + height - 1, - width, 3); - - if (mask2 & 4) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - 1, y + 1, - 3, height); - - - if (mask2 & 8) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x + width - 1, y + 1, - 3, height); - - - - } - - } - - } - } - - - *range = new_range; - gtk_sheet_draw_corners (sheet, new_range); - -} - -static void -gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange new_range) -{ - GtkWidget *widget; - GdkRectangle area; - gint i; - gint x, y, width, height; - - widget = GTK_WIDGET (sheet); - - x = COLUMN_LEFT_XPIXEL (sheet, new_range.col0); - y = ROW_TOP_YPIXEL (sheet, new_range.row0); - width = COLUMN_LEFT_XPIXEL (sheet, new_range.coli) - x + - xxx_column_width (sheet, new_range.coli); - - height = ROW_TOP_YPIXEL (sheet, new_range.rowi) - y + - yyy_row_height (sheet, new_range.rowi); - - area.x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet)); - area.y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet)); - area.width = sheet->sheet_window_width; - area.height = sheet->sheet_window_height; - - if (x < 0) - { - width = width + x; - x = 0; - } - if (width > area.width) width = area.width + 10; - if (y < 0) - { - height = height + y; - y = 0; - } - if (height > area.height) height = area.height + 10; - - gdk_gc_set_clip_rectangle (sheet->xor_gc, &area); - - for (i = -1; i <= 1; ++i) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - FALSE, - x + i, - y + i, - width - 2 * i, - height - 2 * i); - - gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL); - - - gtk_sheet_draw_corners (sheet, new_range); -} + width = width - 2; + } + if (j == new_range.coli) width = width - 3; -static void -gtk_sheet_draw_corners (GtkSheet *sheet, GtkSheetRange range) -{ - gint x, y; - guint width = 1; + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + TRUE, + x + 1, y + 1, + width, height); - if (gtk_sheet_cell_isvisible (sheet, range.row0, range.col0)) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - y = ROW_TOP_YPIXEL (sheet, range.row0); - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - 1, - y - 1, - x - 1, - y - 1, - 3, - 3); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - 1, y - 1, - 3, 3); - } + } - if (gtk_sheet_cell_isvisible (sheet, range.row0, range.coli) || - sheet->state == GTK_SHEET_COLUMN_SELECTED) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+ - xxx_column_width (sheet, range.coli); - y = ROW_TOP_YPIXEL (sheet, range.row0); - width = 1; - if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - { - y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet))+3; - width = 3; } - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); } - if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.col0) || - sheet->state == GTK_SHEET_ROW_SELECTED) + for (i = aux_range.row0; i <= aux_range.rowi; i++) { - x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - y = ROW_TOP_YPIXEL (sheet, range.rowi)+ - yyy_row_height (sheet, range.rowi); - width = 1; - if (sheet->state == GTK_SHEET_ROW_SELECTED) + for (j = aux_range.col0; j <= aux_range.coli; j++) { - x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet))+3; - width = 3; + state = gtk_sheet_cell_get_state (sheet, i, j); + + mask1 = i == sheet->range.row0 ? 1 : 0; + mask1 = i == sheet->range.rowi ? mask1 + 2 : mask1; + mask1 = j == sheet->range.col0 ? mask1 + 4 : mask1; + mask1 = j == sheet->range.coli ? mask1 + 8 : mask1; + + mask2 = i == new_range.row0 ? 1 : 0; + mask2 = i == new_range.rowi ? mask2 + 2 : mask2; + mask2 = j == new_range.col0 ? mask2 + 4 : mask2; + mask2 = j == new_range.coli ? mask2 + 8 : mask2; + if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED)) + { + x = psppire_axis_pixel_start (sheet->haxis, j); + y = psppire_axis_pixel_start (sheet->vaxis, i); + width = psppire_axis_unit_size (sheet->haxis, j); + height = psppire_axis_unit_size (sheet->vaxis, i); + if (mask2 & 1) + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + TRUE, + x + 1, y - 1, + width, 3); + + + if (mask2 & 2) + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + TRUE, + x + 1, y + height - 1, + width, 3); + + if (mask2 & 4) + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + TRUE, + x - 1, y + 1, + 3, height); + + + if (mask2 & 8) + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + TRUE, + x + width - 1, y + 1, + 3, height); + } } - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); } - if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.coli)) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+ - xxx_column_width (sheet, range.coli); - y = ROW_TOP_YPIXEL (sheet, range.rowi)+ - yyy_row_height (sheet, range.rowi); - width = 1; - if (sheet->state == GTK_SHEET_RANGE_SELECTED) width = 3; - if (sheet->state == GTK_SHEET_NORMAL) width = 3; - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); + *range = new_range; +} + - } +static void +gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange new_range) +{ + GdkRectangle area; + + rectangle_from_range (sheet, &new_range, &area); + + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + FALSE, + area.x, + area.y, + area.width + 1, + area.height + 1); } static void -gtk_sheet_real_select_range (GtkSheet * sheet, - const GtkSheetRange * range) +gtk_sheet_real_select_range (GtkSheet *sheet, + const GtkSheetRange *range) { gint state; @@ -4437,6 +2979,7 @@ gtk_sheet_real_select_range (GtkSheet * sheet, state = sheet->state; +#if 0 if (range->coli != sheet->range.coli || range->col0 != sheet->range.col0 || range->rowi != sheet->range.rowi || range->row0 != sheet->range.row0) { @@ -4444,9 +2987,9 @@ gtk_sheet_real_select_range (GtkSheet * sheet, } else { - gtk_sheet_draw_backing_pixmap (sheet, sheet->range); gtk_sheet_range_draw_selection (sheet, sheet->range); } +#endif gtk_sheet_update_primary_selection (sheet); @@ -4455,8 +2998,7 @@ gtk_sheet_real_select_range (GtkSheet * sheet, void -gtk_sheet_get_selected_range (GtkSheet *sheet, - GtkSheetRange *range) +gtk_sheet_get_selected_range (GtkSheet *sheet, GtkSheetRange *range) { g_return_if_fail (sheet != NULL); *range = sheet->range; @@ -4464,7 +3006,7 @@ gtk_sheet_get_selected_range (GtkSheet *sheet, void -gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range) +gtk_sheet_select_range (GtkSheet *sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); @@ -4476,8 +3018,6 @@ gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range) if (sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range (sheet, NULL); - else - gtk_sheet_deactivate_cell (sheet); sheet->range.row0 = range->row0; sheet->range.rowi = range->rowi; @@ -4490,11 +3030,10 @@ gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range) sheet->state = GTK_SHEET_RANGE_SELECTED; gtk_sheet_real_select_range (sheet, NULL); - } void -gtk_sheet_unselect_range (GtkSheet * sheet) +gtk_sheet_unselect_range (GtkSheet *sheet) { if (! GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; @@ -4502,13 +3041,13 @@ gtk_sheet_unselect_range (GtkSheet * sheet) gtk_sheet_real_unselect_range (sheet, NULL); sheet->state = GTK_STATE_NORMAL; - gtk_sheet_activate_cell (sheet, - sheet->active_cell.row, sheet->active_cell.col); + change_active_cell (sheet, + sheet->active_cell.row, sheet->active_cell.col); } static void -gtk_sheet_real_unselect_range (GtkSheet * sheet, +gtk_sheet_real_unselect_range (GtkSheet *sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); @@ -4523,21 +3062,16 @@ gtk_sheet_real_unselect_range (GtkSheet * sheet, g_signal_emit (sheet, sheet_signals[SELECT_COLUMN], 0, -1); g_signal_emit (sheet, sheet_signals[SELECT_ROW], 0, -1); - if (gtk_sheet_range_isvisible (sheet, *range)) - gtk_sheet_draw_backing_pixmap (sheet, *range); - sheet->range.row0 = -1; sheet->range.rowi = -1; sheet->range.col0 = -1; sheet->range.coli = -1; - - gtk_sheet_position_children (sheet); } static gint -gtk_sheet_expose (GtkWidget * widget, - GdkEventExpose * event) +gtk_sheet_expose (GtkWidget *widget, + GdkEventExpose *event) { GtkSheet *sheet; GtkSheetRange range; @@ -4546,60 +3080,76 @@ gtk_sheet_expose (GtkWidget * widget, g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - sheet = GTK_SHEET (widget); - if (GTK_WIDGET_DRAWABLE (widget)) + if (!GTK_WIDGET_DRAWABLE (widget)) + return FALSE; + + /* exposure events on the sheet */ + if (event->window == sheet->row_title_window && + sheet->row_titles_visible) { - range.row0 = ROW_FROM_YPIXEL (sheet, event->area.y); - range.col0 = COLUMN_FROM_XPIXEL (sheet, event->area.x); - range.rowi = ROW_FROM_YPIXEL (sheet, event->area.y + event->area.height); - range.coli = COLUMN_FROM_XPIXEL (sheet, event->area.x + event->area.width); - - /* exposure events on the sheet */ - if (event->window == sheet->row_title_window && - sheet->row_titles_visible) - { - gint i; - for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++) - gtk_sheet_row_title_button_draw (sheet, i); - } + draw_row_title_buttons_range (sheet, + min_visible_row (sheet), + max_visible_row (sheet)); + } - if (event->window == sheet->column_title_window && - sheet->column_titles_visible) - { - gint i; - for (i = MIN_VISIBLE_COLUMN (sheet); i <= MAX_VISIBLE_COLUMN (sheet); i++) - gtk_sheet_column_title_button_draw (sheet, i); - } + if (event->window == sheet->column_title_window && + sheet->column_titles_visible) + { + draw_column_title_buttons_range (sheet, + min_visible_column (sheet), + max_visible_column (sheet)); + } + + + range.row0 = + row_from_ypixel (sheet, + event->area.y + sheet->vadjustment->value); + range.row0--; + + range.rowi = + row_from_ypixel (sheet, + event->area.y + + event->area.height + sheet->vadjustment->value); + range.rowi++; + + range.col0 = + column_from_xpixel (sheet, + event->area.x + sheet->hadjustment->value); + range.col0--; + + range.coli = + column_from_xpixel (sheet, + event->area.x + event->area.width + + sheet->hadjustment->value); + range.coli++; + + + if (event->window == sheet->sheet_window) + { + gtk_sheet_range_draw (sheet, &range); - if (event->window == sheet->sheet_window) + if (sheet->state != GTK_SHEET_NORMAL) { - gtk_sheet_draw_backing_pixmap (sheet, range); + if (gtk_sheet_range_isvisible (sheet, &sheet->range)) + gtk_sheet_range_draw (sheet, &sheet->range); - if (sheet->state != GTK_SHEET_NORMAL) - { - if (gtk_sheet_range_isvisible (sheet, sheet->range)) - gtk_sheet_draw_backing_pixmap (sheet, sheet->range); - if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet)) - gtk_sheet_draw_backing_pixmap (sheet, sheet->drag_range); - - if (gtk_sheet_range_isvisible (sheet, sheet->range)) - gtk_sheet_range_draw_selection (sheet, sheet->range); - if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet)) - draw_xor_rectangle (sheet, sheet->drag_range); - } + if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet)) + gtk_sheet_range_draw (sheet, &sheet->drag_range); - if ((!GTK_SHEET_IN_XDRAG (sheet)) && (!GTK_SHEET_IN_YDRAG (sheet))) - { - if (sheet->state == GTK_SHEET_NORMAL) - gtk_sheet_draw_active_cell (sheet); - } + if (gtk_sheet_range_isvisible (sheet, &sheet->range)) + gtk_sheet_range_draw_selection (sheet, sheet->range); + if (GTK_SHEET_IN_RESIZE (sheet) || GTK_SHEET_IN_DRAG (sheet)) + draw_xor_rectangle (sheet, sheet->drag_range); } - } - if (sheet->state != GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION (sheet)) - gtk_widget_grab_focus (GTK_WIDGET (sheet)); + if ((!GTK_SHEET_IN_XDRAG (sheet)) && (!GTK_SHEET_IN_YDRAG (sheet))) + { + if (sheet->state == GTK_SHEET_NORMAL) + gtk_sheet_draw_active_cell (sheet); + } + } (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); @@ -4608,12 +3158,13 @@ gtk_sheet_expose (GtkWidget * widget, static gboolean -gtk_sheet_button_press (GtkWidget * widget, - GdkEventButton * event) +gtk_sheet_button_press (GtkWidget *widget, + GdkEventButton *event) { GtkSheet *sheet; GdkModifierType mods; - gint x, y, row, column; + gint x, y; + gint row, column; gboolean veto; g_return_val_if_fail (widget != NULL, FALSE); @@ -4639,10 +3190,12 @@ gtk_sheet_button_press (GtkWidget * widget, sheet_signals[BUTTON_EVENT_COLUMN], 0, column, event); - if ( event->type == GDK_2BUTTON_PRESS && event->button == 1) - g_signal_emit (sheet, - sheet_signals[DOUBLE_CLICK_COLUMN], 0, column); - + if (g_sheet_model_get_column_sensitivity (sheet->model, column)) + { + if ( event->type == GDK_2BUTTON_PRESS && event->button == 1) + g_signal_emit (sheet, + sheet_signals[DOUBLE_CLICK_COLUMN], 0, column); + } } else if (event->window == sheet->row_title_window) { @@ -4650,12 +3203,14 @@ gtk_sheet_button_press (GtkWidget * widget, sheet_signals[BUTTON_EVENT_ROW], 0, row, event); - if ( event->type == GDK_2BUTTON_PRESS && event->button == 1) - g_signal_emit (sheet, - sheet_signals[DOUBLE_CLICK_ROW], 0, row); + if (g_sheet_model_get_row_sensitivity (sheet->model, row)) + { + if ( event->type == GDK_2BUTTON_PRESS && event->button == 1) + g_signal_emit (sheet, + sheet_signals[DOUBLE_CLICK_ROW], 0, row); + } } - gdk_window_get_pointer (widget->window, NULL, NULL, &mods); if (! (mods & GDK_BUTTON1_MASK)) return TRUE; @@ -4665,16 +3220,17 @@ gtk_sheet_button_press (GtkWidget * widget, if (event->window == sheet->column_title_window && gtk_sheet_columns_resizable (sheet)) { +#if 0 gtk_widget_get_pointer (widget, &sheet->x_drag, NULL); - if (POSSIBLE_XDRAG (sheet, sheet->x_drag, &sheet->drag_cell.col)) + if ( sheet->row_titles_visible) + sheet->x_drag -= sheet->row_title_area.width; +#endif + + sheet->x_drag = event->x; + + if (on_column_boundary (sheet, sheet->x_drag, &sheet->drag_cell.col)) { guint req; - if (event->type == GDK_2BUTTON_PRESS) - { - gtk_sheet_autoresize_column (sheet, sheet->drag_cell.col); - GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG); - return TRUE; - } gtk_sheet_column_size_request (sheet, sheet->drag_cell.col, &req); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_XDRAG); gdk_pointer_grab (sheet->column_title_window, FALSE, @@ -4692,6 +3248,7 @@ gtk_sheet_button_press (GtkWidget * widget, { gtk_widget_get_pointer (widget, NULL, &sheet->y_drag); +#if AXIS_TRANSITION if (POSSIBLE_YDRAG (sheet, sheet->y_drag, &sheet->drag_cell.row)) { guint req; @@ -4706,6 +3263,7 @@ gtk_sheet_button_press (GtkWidget * widget, draw_xor_hline (sheet); return TRUE; } +#endif } /* the sheet itself does not handle other than single click events */ @@ -4738,7 +3296,6 @@ gtk_sheet_button_press (GtkWidget * widget, { row = sheet->active_cell.row; column = sheet->active_cell.col; - gtk_sheet_deactivate_cell (sheet); sheet->active_cell.row = row; sheet->active_cell.col = column; sheet->drag_range = sheet->range; @@ -4766,7 +3323,6 @@ gtk_sheet_button_press (GtkWidget * widget, { row = sheet->active_cell.row; column = sheet->active_cell.col; - gtk_sheet_deactivate_cell (sheet); sheet->active_cell.row = row; sheet->active_cell.col = column; sheet->drag_range = sheet->range; @@ -4787,7 +3343,7 @@ gtk_sheet_button_press (GtkWidget * widget, } else { - gtk_sheet_click_cell (sheet, row, column, &veto); + veto = gtk_sheet_click_cell (sheet, row, column); if (veto) GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); } } @@ -4795,11 +3351,16 @@ gtk_sheet_button_press (GtkWidget * widget, if (event->window == sheet->column_title_window) { gtk_widget_get_pointer (widget, &x, &y); - column = COLUMN_FROM_XPIXEL (sheet, x); + if ( sheet->row_titles_visible) + x -= sheet->row_title_area.width; + + x += sheet->hadjustment->value; - if (xxx_column_is_sensitive (sheet, column)) + column = column_from_xpixel (sheet, x); + + if (g_sheet_model_get_column_sensitivity (sheet->model, column)) { - gtk_sheet_click_cell (sheet, - 1, column, &veto); + veto = gtk_sheet_click_cell (sheet, -1, column); gtk_grab_add (GTK_WIDGET (sheet)); gtk_widget_grab_focus (GTK_WIDGET (sheet)); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); @@ -4809,10 +3370,15 @@ gtk_sheet_button_press (GtkWidget * widget, if (event->window == sheet->row_title_window) { gtk_widget_get_pointer (widget, &x, &y); - row = ROW_FROM_YPIXEL (sheet, y); - if (yyy_row_is_sensitive (sheet, row)) + if ( sheet->column_titles_visible) + y -= sheet->column_title_area.height; + + y += sheet->vadjustment->value; + + row = row_from_ypixel (sheet, y); + if (g_sheet_model_get_row_sensitivity (sheet->model, row)) { - gtk_sheet_click_cell (sheet, row, - 1, &veto); + veto = gtk_sheet_click_cell (sheet, row, -1); gtk_grab_add (GTK_WIDGET (sheet)); gtk_widget_grab_focus (GTK_WIDGET (sheet)); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); @@ -4822,122 +3388,110 @@ gtk_sheet_button_press (GtkWidget * widget, return TRUE; } -static void -gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto) +static gboolean +gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column) { - *veto = TRUE; + GtkSheetCell cell; + gboolean forbid_move; + + cell.row = row; + cell.col = column; - if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet)) + if (row >= psppire_axis_unit_count (sheet->vaxis) + || column >= psppire_axis_unit_count (sheet->haxis)) { - *veto = FALSE; - return; + return FALSE; } - if (column >= 0 && row >= 0) - if (! xxx_column_is_visible (sheet, column) || !yyy_row_is_visible (sheet, row)) - { - *veto = FALSE; - return; - } - - _gtkextra_signal_emit (GTK_OBJECT (sheet), sheet_signals[TRAVERSE], - sheet->active_cell.row, sheet->active_cell.col, - &row, &column, veto); + g_signal_emit (sheet, sheet_signals[TRAVERSE], 0, + &sheet->active_cell, + &cell, + &forbid_move); - if (!*veto) + if (forbid_move) { - if (sheet->state == GTK_STATE_NORMAL) return; + if (sheet->state == GTK_STATE_NORMAL) + return FALSE; row = sheet->active_cell.row; column = sheet->active_cell.col; - gtk_sheet_activate_cell (sheet, row, column); - return; + change_active_cell (sheet, row, column); + return FALSE; } if (row == -1 && column >= 0) { - if (gtk_sheet_autoscroll (sheet)) - gtk_sheet_move_query (sheet, row, column); gtk_sheet_select_column (sheet, column); - return; + return TRUE; } + if (column == -1 && row >= 0) { - if (gtk_sheet_autoscroll (sheet)) - gtk_sheet_move_query (sheet, row, column); gtk_sheet_select_row (sheet, row); - return; + return TRUE; } - if (row == - 1 && column == - 1) + if (row == -1 && column == -1) { sheet->range.row0 = 0; sheet->range.col0 = 0; - sheet->range.rowi = yyy_row_count (sheet) - 1; - sheet->range.coli = xxx_column_count (sheet) - 1; + sheet->range.rowi = psppire_axis_unit_count (sheet->vaxis) - 1; + sheet->range.coli = + psppire_axis_unit_count (sheet->haxis) - 1; sheet->active_cell.row = 0; sheet->active_cell.col = 0; gtk_sheet_select_range (sheet, NULL); - return; + return TRUE; } - if (row != -1 && column != -1) + if (sheet->state != GTK_SHEET_NORMAL) { - if (sheet->state != GTK_SHEET_NORMAL) - { - sheet->state = GTK_SHEET_NORMAL; - gtk_sheet_real_unselect_range (sheet, NULL); - } - else - { - gtk_sheet_deactivate_cell (sheet); - gtk_sheet_activate_cell (sheet, row, column); - } - - if (gtk_sheet_autoscroll (sheet)) - gtk_sheet_move_query (sheet, row, column); - sheet->active_cell.row = row; - sheet->active_cell.col = column; - sheet->selection_cell.row = row; - sheet->selection_cell.col = column; - sheet->range.row0 = row; - sheet->range.col0 = column; - sheet->range.rowi = row; - sheet->range.coli = column; sheet->state = GTK_SHEET_NORMAL; - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); - gtk_sheet_draw_active_cell (sheet); - return; + gtk_sheet_real_unselect_range (sheet, NULL); + } + else + { + change_active_cell (sheet, row, column); } - g_assert_not_reached (); - gtk_sheet_activate_cell (sheet, sheet->active_cell.row, - sheet->active_cell.col); + sheet->active_cell.row = row; + sheet->active_cell.col = column; + sheet->selection_cell.row = row; + sheet->selection_cell.col = column; + sheet->range.row0 = row; + sheet->range.col0 = column; + sheet->range.rowi = row; + sheet->range.coli = column; + sheet->state = GTK_SHEET_NORMAL; + GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); + gtk_sheet_draw_active_cell (sheet); + return TRUE; } static gint -gtk_sheet_button_release (GtkWidget * widget, - GdkEventButton * event) +gtk_sheet_button_release (GtkWidget *widget, + GdkEventButton *event) { - GtkSheet *sheet; - gint x, y; + gint y; + GdkDisplay *display = gtk_widget_get_display (widget); - sheet = GTK_SHEET (widget); + GtkSheet *sheet = GTK_SHEET (widget); /* release on resize windows */ if (GTK_SHEET_IN_XDRAG (sheet)) { + gint xpos = event->x; + gint width; GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); - gtk_widget_get_pointer (widget, &x, NULL); - gdk_pointer_ungrab (event->time); + + gdk_display_pointer_ungrab (display, event->time); draw_xor_vline (sheet); - gtk_sheet_set_column_width (sheet, sheet->drag_cell.col, - new_column_width (sheet, sheet->drag_cell.col, &x)); - sheet->old_hadjustment = -1.; - g_signal_emit_by_name (sheet->hadjustment, "value_changed"); + width = new_column_width (sheet, sheet->drag_cell.col, &xpos); + + gtk_sheet_set_column_width (sheet, sheet->drag_cell.col, width); return TRUE; } @@ -4946,11 +3500,11 @@ gtk_sheet_button_release (GtkWidget * widget, GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_YDRAG); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); gtk_widget_get_pointer (widget, NULL, &y); - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (display, event->time); draw_xor_hline (sheet); - gtk_sheet_set_row_height (sheet, sheet->drag_cell.row, new_row_height (sheet, sheet->drag_cell.row, &y)); - sheet->old_vadjustment = -1.; + gtk_sheet_set_row_height (sheet, sheet->drag_cell.row, + new_row_height (sheet, sheet->drag_cell.row, &y)); g_signal_emit_by_name (sheet->vadjustment, "value_changed"); return TRUE; } @@ -4961,7 +3515,7 @@ gtk_sheet_button_release (GtkWidget * widget, GtkSheetRange old_range; draw_xor_rectangle (sheet, sheet->drag_range); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_DRAG); - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (display, event->time); gtk_sheet_real_unselect_range (sheet, NULL); @@ -4986,7 +3540,7 @@ gtk_sheet_button_release (GtkWidget * widget, GtkSheetRange old_range; draw_xor_rectangle (sheet, sheet->drag_range); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_RESIZE); - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (display, event->time); gtk_sheet_real_unselect_range (sheet, NULL); @@ -5015,13 +3569,13 @@ gtk_sheet_button_release (GtkWidget * widget, if (sheet->state == GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION (sheet)) { GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); - gdk_pointer_ungrab (event->time); - gtk_sheet_activate_cell (sheet, sheet->active_cell.row, + gdk_display_pointer_ungrab (display, event->time); + change_active_cell (sheet, sheet->active_cell.row, sheet->active_cell.col); } if (GTK_SHEET_IN_SELECTION) - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (display, event->time); gtk_grab_remove (GTK_WIDGET (sheet)); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); @@ -5029,6 +3583,10 @@ gtk_sheet_button_release (GtkWidget * widget, return TRUE; } + + + + /* Shamelessly lifted from gtktooltips */ static gboolean gtk_sheet_subtitle_paint_window (GtkWidget *tip_window) @@ -5044,10 +3602,17 @@ gtk_sheet_subtitle_paint_window (GtkWidget *tip_window) return FALSE; } +static void +destroy_hover_window (GtkSheetHoverTitle *h) +{ + gtk_widget_destroy (h->window); + g_free (h); +} + static GtkSheetHoverTitle * create_hover_window (void) { - GtkSheetHoverTitle *hw = malloc (sizeof (*hw)); + GtkSheetHoverTitle *hw = g_malloc (sizeof (*hw)); hw->window = gtk_window_new (GTK_WINDOW_POPUP); @@ -5096,16 +3661,6 @@ show_subtitle (GtkSheet *sheet, gint row, gint column, const gchar *subtitle) if ( ! subtitle ) return; - if ( ! sheet->hover_window) - { - sheet->hover_window = create_hover_window (); - gtk_widget_add_events (GTK_WIDGET (sheet), GDK_LEAVE_NOTIFY_MASK); - - g_signal_connect_swapped (sheet, "leave-notify-event", - G_CALLBACK (gtk_widget_hide), - sheet->hover_window->window); - } - gtk_label_set_text (GTK_LABEL (sheet->hover_window->label), subtitle); @@ -5151,28 +3706,20 @@ motion_timeout_callback (gpointer data) if ( gtk_sheet_get_pixel_info (sheet, x, y, &row, &column) ) { - if ( column == -1 && row == -1 ) - return FALSE; - - if ( column == -1) + if (sheet->row_title_under) { - GSheetRow *row_geo = sheet->row_geometry; - gchar *text; + gchar *text = g_sheet_model_get_row_subtitle (sheet->model, row); - text = g_sheet_row_get_subtitle (row_geo, row); - - show_subtitle (sheet, row, column, text); + show_subtitle (sheet, row, -1, text); g_free (text); } - if ( row == -1) + if (sheet->column_title_under) { - GSheetColumn *col_geo = sheet->column_geometry; - gchar *text; - - text = g_sheet_column_get_subtitle (col_geo, column); + gchar *text = g_sheet_model_get_column_subtitle (sheet->model, + column); - show_subtitle (sheet, row, column, text ); + show_subtitle (sheet, -1, column, text); g_free (text); } @@ -5181,15 +3728,15 @@ motion_timeout_callback (gpointer data) return FALSE; } -static gint -gtk_sheet_motion (GtkWidget * widget, - GdkEventMotion * event) +static gboolean +gtk_sheet_motion (GtkWidget *widget, GdkEventMotion *event) { GtkSheet *sheet; GdkModifierType mods; GdkCursorType new_cursor; gint x, y; gint row, column; + GdkDisplay *display; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); @@ -5197,15 +3744,18 @@ gtk_sheet_motion (GtkWidget * widget, sheet = GTK_SHEET (widget); + display = gtk_widget_get_display (widget); + /* selections on the sheet */ x = event->x; y = event->y; - if (!sheet->hover_window || ! GTK_WIDGET_VISIBLE (sheet->hover_window->window)) + if (!GTK_WIDGET_VISIBLE (sheet->hover_window->window)) { if ( sheet->motion_timer > 0 ) g_source_remove (sheet->motion_timer); - sheet->motion_timer = g_timeout_add (TIMEOUT_HOVER, motion_timeout_callback, sheet); + sheet->motion_timer = + g_timeout_add (TIMEOUT_HOVER, motion_timeout_callback, sheet); } else { @@ -5215,7 +3765,8 @@ gtk_sheet_motion (GtkWidget * widget, if ( gtk_sheet_get_pixel_info (sheet, wx, wy, &row, &column) ) { - if ( row != sheet->hover_window->row || column != sheet->hover_window->column) + if ( row != sheet->hover_window->row || + column != sheet->hover_window->column) { gtk_widget_hide (sheet->hover_window->window); } @@ -5225,15 +3776,14 @@ gtk_sheet_motion (GtkWidget * widget, if (event->window == sheet->column_title_window && gtk_sheet_columns_resizable (sheet)) { - gtk_widget_get_pointer (widget, &x, &y); if (!GTK_SHEET_IN_SELECTION (sheet) && - POSSIBLE_XDRAG (sheet, x, &column)) + on_column_boundary (sheet, x, &column)) { new_cursor = GDK_SB_H_DOUBLE_ARROW; if (new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_SB_H_DOUBLE_ARROW); gdk_window_set_cursor (sheet->column_title_window, sheet->cursor_drag); } @@ -5245,7 +3795,7 @@ gtk_sheet_motion (GtkWidget * widget, new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW); gdk_window_set_cursor (sheet->column_title_window, sheet->cursor_drag); } @@ -5255,25 +3805,26 @@ gtk_sheet_motion (GtkWidget * widget, if (event->window == sheet->row_title_window && gtk_sheet_rows_resizable (sheet)) { - gtk_widget_get_pointer (widget, &x, &y); +#if AXIS_TRANSITION if (!GTK_SHEET_IN_SELECTION (sheet) && POSSIBLE_YDRAG (sheet, y, &column)) { new_cursor = GDK_SB_V_DOUBLE_ARROW; if (new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_SB_V_DOUBLE_ARROW); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_SB_V_DOUBLE_ARROW); gdk_window_set_cursor (sheet->row_title_window, sheet->cursor_drag); } } else +#endif { new_cursor = GDK_TOP_LEFT_ARROW; if (!GTK_SHEET_IN_YDRAG (sheet) && new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW); gdk_window_set_cursor (sheet->row_title_window, sheet->cursor_drag); } } @@ -5288,18 +3839,20 @@ gtk_sheet_motion (GtkWidget * widget, new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_PLUS); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_PLUS); gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag); } new_cursor = GDK_TOP_LEFT_ARROW; if ( event->window == sheet->sheet_window && - ! (POSSIBLE_RESIZE (sheet, x, y, &row, &column) || GTK_SHEET_IN_RESIZE (sheet)) && (POSSIBLE_DRAG (sheet, x, y, &row, &column) || GTK_SHEET_IN_DRAG (sheet)) && - + ! (POSSIBLE_RESIZE (sheet, x, y, &row, &column) || + GTK_SHEET_IN_RESIZE (sheet)) && + (POSSIBLE_DRAG (sheet, x, y, &row, &column) || + GTK_SHEET_IN_DRAG (sheet)) && new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_TOP_LEFT_ARROW); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_TOP_LEFT_ARROW); gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag); } @@ -5312,7 +3865,7 @@ gtk_sheet_motion (GtkWidget * widget, new_cursor != sheet->cursor_drag->type) { gdk_cursor_unref (sheet->cursor_drag); - sheet->cursor_drag = gdk_cursor_new (GDK_SIZING); + sheet->cursor_drag = gdk_cursor_new_for_display (display, GDK_SIZING); gdk_window_set_cursor (sheet->sheet_window, sheet->cursor_drag); } @@ -5322,18 +3875,17 @@ gtk_sheet_motion (GtkWidget * widget, if (GTK_SHEET_IN_XDRAG (sheet)) { - if (event->is_hint || event->window != widget->window) - gtk_widget_get_pointer (widget, &x, NULL); - else - x = event->x; + x = event->x; new_column_width (sheet, sheet->drag_cell.col, &x); +#if 0 if (x != sheet->x_drag) { draw_xor_vline (sheet); sheet->x_drag = x; draw_xor_vline (sheet); } +#endif return TRUE; } @@ -5357,15 +3909,15 @@ gtk_sheet_motion (GtkWidget * widget, if (GTK_SHEET_IN_DRAG (sheet)) { GtkSheetRange aux; - column = COLUMN_FROM_XPIXEL (sheet, x)- sheet->drag_cell.col; - row = ROW_FROM_YPIXEL (sheet, y)- sheet->drag_cell.row; + column = column_from_xpixel (sheet, x)- sheet->drag_cell.col; + row = row_from_ypixel (sheet, y) - sheet->drag_cell.row; if (sheet->state == GTK_SHEET_COLUMN_SELECTED) row = 0; if (sheet->state == GTK_SHEET_ROW_SELECTED) column = 0; sheet->x_drag = x; sheet->y_drag = y; aux = sheet->range; - if (aux.row0 + row >= 0 && aux.rowi + row < yyy_row_count (sheet) && - aux.col0 + column >= 0 && aux.coli + column < xxx_column_count (sheet)) + if (aux.row0 + row >= 0 && aux.rowi + row < psppire_axis_unit_count (sheet->vaxis) && + aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis)) { aux = sheet->drag_range; sheet->drag_range.row0 = sheet->range.row0 + row; @@ -5387,19 +3939,18 @@ gtk_sheet_motion (GtkWidget * widget, GtkSheetRange aux; gint v_h, current_col, current_row, col_threshold, row_threshold; v_h = 1; + if (abs (x - psppire_axis_pixel_start (sheet->haxis, sheet->drag_cell.col)) > + abs (y - psppire_axis_pixel_start (sheet->vaxis, sheet->drag_cell.row))) v_h = 2; - if (abs (x - COLUMN_LEFT_XPIXEL (sheet, sheet->drag_cell.col)) > - abs (y - ROW_TOP_YPIXEL (sheet, sheet->drag_cell.row))) v_h = 2; - - current_col = COLUMN_FROM_XPIXEL (sheet, x); - current_row = ROW_FROM_YPIXEL (sheet, y); + current_col = column_from_xpixel (sheet, x); + current_row = row_from_ypixel (sheet, y); column = current_col - sheet->drag_cell.col; row = current_row - sheet->drag_cell.row; /*use half of column width resp. row height as threshold to expand selection*/ - col_threshold = COLUMN_LEFT_XPIXEL (sheet, current_col) + - xxx_column_width (sheet, current_col) / 2; + col_threshold = psppire_axis_pixel_start (sheet->haxis, current_col) + + psppire_axis_unit_size (sheet->haxis, current_col) / 2; if (column > 0) { if (x < col_threshold) @@ -5410,8 +3961,8 @@ gtk_sheet_motion (GtkWidget * widget, if (x > col_threshold) column +=1; } - row_threshold = ROW_TOP_YPIXEL (sheet, current_row) + - yyy_row_height (sheet, current_row)/2; + row_threshold = psppire_axis_pixel_start (sheet->vaxis, current_row) + + psppire_axis_unit_size (sheet->vaxis, current_row)/2; if (row > 0) { if (y < row_threshold) @@ -5434,8 +3985,8 @@ gtk_sheet_motion (GtkWidget * widget, else row = 0; - if (aux.row0 + row >= 0 && aux.rowi + row < yyy_row_count (sheet) && - aux.col0 + column >= 0 && aux.coli + column < xxx_column_count (sheet)) + if (aux.row0 + row >= 0 && aux.rowi + row < psppire_axis_unit_count (sheet->vaxis) && + aux.col0 + column >= 0 && aux.coli + column < psppire_axis_unit_count (sheet->haxis)) { aux = sheet->drag_range; sheet->drag_range = sheet->range; @@ -5469,65 +4020,17 @@ gtk_sheet_motion (GtkWidget * widget, } static gboolean -gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column) +gtk_sheet_crossing_notify (GtkWidget *widget, + GdkEventCrossing *event) { - gint row_move, column_move; - gfloat row_align, col_align; - guint height, width; - gint new_row = row; - gint new_col = column; - - row_move = FALSE; - column_move = FALSE; - row_align = -1.; - col_align = -1.; - - height = sheet->sheet_window_height; - width = sheet->sheet_window_width; - - if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED) - { - row_align = 1.; - new_row = MIN (yyy_row_count (sheet) - 1, row + 1); - row_move = TRUE; - if (MAX_VISIBLE_ROW (sheet) == yyy_row_count (sheet) - 1 && - ROW_TOP_YPIXEL (sheet, yyy_row_count (sheet)- 1) + - yyy_row_height (sheet, yyy_row_count (sheet)- 1) < height) - { - row_move = FALSE; - row_align = -1.; - } - } - if (row < MIN_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED) - { - row_align= 0.; - row_move = TRUE; - } - if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED) - { - col_align = 1.; - new_col = MIN (xxx_column_count (sheet) - 1, column + 1); - column_move = TRUE; - if (MAX_VISIBLE_COLUMN (sheet) == (xxx_column_count (sheet) - 1) && - COLUMN_LEFT_XPIXEL (sheet, xxx_column_count (sheet) - 1) + - xxx_column_width (sheet, xxx_column_count (sheet) - 1) < width) - { - column_move = FALSE; - col_align = -1.; - } - } - if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED) - { - col_align = 0.; - column_move = TRUE; - } + GtkSheet *sheet = GTK_SHEET (widget); - if (row_move || column_move) - { - gtk_sheet_moveto (sheet, new_row, new_col, row_align, col_align); - } + if (event->window == sheet->column_title_window) + sheet->column_title_under = event->type == GDK_ENTER_NOTIFY; + else if (event->window == sheet->row_title_window) + sheet->row_title_under = event->type == GDK_ENTER_NOTIFY; - return (row_move || column_move); + return TRUE; } static void @@ -5542,7 +4045,6 @@ gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column) if (sheet->selection_mode == GTK_SELECTION_SINGLE) return; - gtk_sheet_move_query (sheet, row, column); gtk_widget_grab_focus (GTK_WIDGET (sheet)); if (GTK_SHEET_IN_DRAG (sheet)) return; @@ -5552,10 +4054,10 @@ gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column) switch (sheet->state) { case GTK_SHEET_ROW_SELECTED: - column = xxx_column_count (sheet) - 1; + column = psppire_axis_unit_count (sheet->haxis) - 1; break; case GTK_SHEET_COLUMN_SELECTED: - row = yyy_row_count (sheet) - 1; + row = psppire_axis_unit_count (sheet->vaxis) - 1; break; case GTK_SHEET_NORMAL: sheet->state = GTK_SHEET_RANGE_SELECTED; @@ -5565,15 +4067,6 @@ gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column) sheet->range.row0 = r; sheet->range.coli = c; sheet->range.rowi = r; - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - COLUMN_LEFT_XPIXEL (sheet, c)- 1, - ROW_TOP_YPIXEL (sheet, r)- 1, - COLUMN_LEFT_XPIXEL (sheet, c)- 1, - ROW_TOP_YPIXEL (sheet, r)- 1, - xxx_column_width (sheet, c)+4, - yyy_row_height (sheet, r)+4); gtk_sheet_range_draw_selection (sheet, sheet->range); case GTK_SHEET_RANGE_SELECTED: sheet->state = GTK_SHEET_RANGE_SELECTED; @@ -5587,287 +4080,230 @@ gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column) range.row0 = MIN (row, sheet->active_cell.row); range.rowi = MAX (row, sheet->active_cell.row); - if (range.row0 != sheet->range.row0 || range.rowi != sheet->range.rowi || - range.col0 != sheet->range.col0 || range.coli != sheet->range.coli || - state == GTK_SHEET_NORMAL) - gtk_sheet_real_select_range (sheet, &range); + if (range.row0 != sheet->range.row0 || range.rowi != sheet->range.rowi || + range.col0 != sheet->range.col0 || range.coli != sheet->range.coli || + state == GTK_SHEET_NORMAL) + gtk_sheet_real_select_range (sheet, &range); + +} + +static gint +gtk_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 (GtkSheet *sheet, GtkScrollType dir) +{ + gint old_row = sheet->active_cell.row ; + glong vpixel = psppire_axis_pixel_start (sheet->vaxis, old_row); + + gint new_row; + + vpixel -= psppire_axis_pixel_start (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_pixel_start (sheet->vaxis, + min_visible_row (sheet)); + + new_row = row_from_ypixel (sheet, vpixel); + + change_active_cell (sheet, new_row, + sheet->active_cell.col); +} + + +static void +step_sheet (GtkSheet *sheet, GtkScrollType dir) +{ + gint current_row = sheet->active_cell.row; + gint current_col = sheet->active_cell.col; + GtkSheetCell new_cell ; + gboolean forbidden = FALSE; + + new_cell.row = current_row; + new_cell.col = current_col; + + switch ( dir) + { + case GTK_SCROLL_STEP_DOWN: + new_cell.row++; + break; + case GTK_SCROLL_STEP_UP: + new_cell.row--; + break; + case GTK_SCROLL_STEP_RIGHT: + new_cell.col++; + break; + case GTK_SCROLL_STEP_LEFT: + new_cell.col--; + break; + default: + g_assert_not_reached (); + break; + } + + + 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); + + g_signal_emit (sheet, sheet_signals[TRAVERSE], 0, + &sheet->active_cell, + &new_cell, + &forbidden); + + if (forbidden) + return; + + change_active_cell (sheet, new_cell.row, new_cell.col); + + if ( new_cell.col > max_fully_visible_column (sheet)) + { + glong hpos = + psppire_axis_pixel_start (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_pixel_start (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_pixel_start (sheet->vaxis, + new_cell.row + 1); + vpos -= sheet->vadjustment->page_size; -static gint -gtk_sheet_entry_key_press (GtkWidget *widget, - GdkEventKey *key) -{ - gboolean focus; - g_signal_emit_by_name (widget, "key_press_event", key, &focus); - return focus; + gtk_adjustment_set_value (sheet->vadjustment, + vpos); + } + else if ( new_cell.row < min_fully_visible_row (sheet)) + { + glong vpos = + psppire_axis_pixel_start (sheet->vaxis, + new_cell.row); + + gtk_adjustment_set_value (sheet->vadjustment, + vpos); + } } -static gint + +static gboolean gtk_sheet_key_press (GtkWidget *widget, GdkEventKey *key) { - GtkSheet *sheet; - gint row, col; - gint state; - gboolean extend_selection = FALSE; - gboolean force_move = FALSE; - gboolean in_selection = FALSE; - gboolean veto = TRUE; - gint scroll = 1; - - sheet = GTK_SHEET (widget); - - if (key->state & GDK_CONTROL_MASK || key->keyval == GDK_Control_L || - key->keyval == GDK_Control_R) return FALSE; - - extend_selection = (key->state & GDK_SHIFT_MASK) || key->keyval == GDK_Shift_L - || key->keyval == GDK_Shift_R; + GtkSheet *sheet = GTK_SHEET (widget); - state = sheet->state; - in_selection = GTK_SHEET_IN_SELECTION (sheet); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); switch (key->keyval) { - case GDK_Return: case GDK_KP_Enter: - if (sheet->state == GTK_SHEET_NORMAL && - !GTK_SHEET_IN_SELECTION (sheet)) - g_signal_stop_emission_by_name (gtk_sheet_get_entry (sheet), - "key-press-event"); - row = sheet->active_cell.row; - col = sheet->active_cell.col; - if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet)- 1; - if (sheet->state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet); - if (row < yyy_row_count (sheet) - 1) - { - row = row + scroll; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) - row++; - } - gtk_sheet_click_cell (sheet, row, col, &veto); - extend_selection = FALSE; + case GDK_Tab: + case GDK_Right: + step_sheet (sheet, GTK_SCROLL_STEP_RIGHT); break; case GDK_ISO_Left_Tab: - row = sheet->active_cell.row; - col = sheet->active_cell.col; - if (sheet->state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet)- 1; - if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet); - if (col > 0) - { - col = col - scroll; - while (! xxx_column_is_visible (sheet, col) && col > 0) col--; - col = MAX (0, col); - } - gtk_sheet_click_cell (sheet, row, col, &veto); - extend_selection = FALSE; + case GDK_Left: + step_sheet (sheet, GTK_SCROLL_STEP_LEFT); break; - case GDK_Tab: - row = sheet->active_cell.row; - col = sheet->active_cell.col; - if (sheet->state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet)- 1; - if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet); - if (col < xxx_column_count (sheet) - 1) - { - col = col + scroll; - while (! xxx_column_is_visible (sheet, col) && - col < xxx_column_count (sheet) - 1) - col++; - } - gtk_sheet_click_cell (sheet, row, col, &veto); - extend_selection = FALSE; + case GDK_Return: + case GDK_Down: + step_sheet (sheet, GTK_SCROLL_STEP_DOWN); break; - case GDK_Page_Up: - scroll = MAX_VISIBLE_ROW (sheet)- MIN_VISIBLE_ROW (sheet)+1; case GDK_Up: - if (extend_selection) - { - if (state == GTK_STATE_NORMAL) - { - row = sheet->active_cell.row; - col = sheet->active_cell.col; - gtk_sheet_click_cell (sheet, row, col, &veto); - if (!veto) break; - } - if (sheet->selection_cell.row > 0) - { - row = sheet->selection_cell.row - scroll; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; - row = MAX (0, row); - gtk_sheet_extend_selection (sheet, row, sheet->selection_cell.col); - } - return TRUE; - } - col = sheet->active_cell.col; - row = sheet->active_cell.row; - if (state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet); - if (state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet); - row = row - scroll; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; - row = MAX (0, row); - gtk_sheet_click_cell (sheet, row, col, &veto); - extend_selection = FALSE; + step_sheet (sheet, GTK_SCROLL_STEP_UP); break; + case GDK_Page_Down: - scroll = MAX_VISIBLE_ROW (sheet)- MIN_VISIBLE_ROW (sheet)+1; - case GDK_Down: - if (extend_selection) - { - if (state == GTK_STATE_NORMAL) - { - row = sheet->active_cell.row; - col = sheet->active_cell.col; - gtk_sheet_click_cell (sheet, row, col, &veto); - if (!veto) break; - } - if (sheet->selection_cell.row < yyy_row_count (sheet)- 1) - { - row = sheet->selection_cell.row + scroll; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) row++; - row = MIN (yyy_row_count (sheet)- 1, row); - gtk_sheet_extend_selection (sheet, row, sheet->selection_cell.col); - } - return TRUE; - } - col = sheet->active_cell.col; - row = sheet->active_cell.row; - if (sheet->active_cell.row < yyy_row_count (sheet)- 1) - { - if (state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet)- 1; - if (state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet); - row = row + scroll; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) row++; - row = MIN (yyy_row_count (sheet)- 1, row); - } - gtk_sheet_click_cell (sheet, row, col, &veto); - extend_selection = FALSE; - break; - case GDK_Right: - if (extend_selection) - { - if (state == GTK_STATE_NORMAL) - { - row = sheet->active_cell.row; - col = sheet->active_cell.col; - gtk_sheet_click_cell (sheet, row, col, &veto); - if (!veto) break; - } - if (sheet->selection_cell.col < xxx_column_count (sheet) - 1) - { - col = sheet->selection_cell.col + 1; - while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1) - col++; - gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col); - } - return TRUE; - } - col = sheet->active_cell.col; - row = sheet->active_cell.row; - if (sheet->active_cell.col < xxx_column_count (sheet) - 1) - { - col ++; - if (state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet)- 1; - if (state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet); - while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1) col++; - if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0 - || force_move) - { - gtk_sheet_click_cell (sheet, row, col, &veto); - } - else - return FALSE; - } - extend_selection = FALSE; + page_vertical (sheet, GTK_SCROLL_PAGE_DOWN); break; - case GDK_Left: - if (extend_selection) - { - if (state == GTK_STATE_NORMAL) - { - row = sheet->active_cell.row; - col = sheet->active_cell.col; - gtk_sheet_click_cell (sheet, row, col, &veto); - if (!veto) break; - } - if (sheet->selection_cell.col > 0) - { - col = sheet->selection_cell.col - 1; - while (! xxx_column_is_visible (sheet, col) && col > 0) col--; - gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col); - } - return TRUE; - } - col = sheet->active_cell.col - 1; - row = sheet->active_cell.row; - if (state == GTK_SHEET_ROW_SELECTED) - col = MIN_VISIBLE_COLUMN (sheet)- 1; - if (state == GTK_SHEET_COLUMN_SELECTED) - row = MIN_VISIBLE_ROW (sheet); - while (! xxx_column_is_visible (sheet, col) && col > 0) col--; - col = MAX (0, col); - - if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0 - || force_move) - { - gtk_sheet_click_cell (sheet, row, col, &veto); - } - else - return FALSE; - extend_selection = FALSE; + case GDK_Page_Up: + page_vertical (sheet, GTK_SCROLL_PAGE_UP); break; + case GDK_Home: - row = 0; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet) - 1) row++; - gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto); - extend_selection = FALSE; + gtk_adjustment_set_value (sheet->vadjustment, + sheet->vadjustment->lower); + + change_active_cell (sheet, 0, + sheet->active_cell.col); + break; + case GDK_End: - row = yyy_row_count (sheet) - 1; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; - gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto); - extend_selection = FALSE; + gtk_adjustment_set_value (sheet->vadjustment, + sheet->vadjustment->upper - + sheet->vadjustment->page_size - + sheet->vadjustment->page_increment); + + /* + change_active_cellx (sheet, + psppire_axis_unit_count (sheet->vaxis) - 1, + sheet->active_cell.col); + */ + break; + case GDK_Delete: + gtk_sheet_real_cell_clear (sheet, sheet->active_cell.row, sheet->active_cell.col); break; default: - if (in_selection) - { - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); - if (extend_selection) return TRUE; - } - if (state == GTK_SHEET_ROW_SELECTED) - sheet->active_cell.col = MIN_VISIBLE_COLUMN (sheet); - if (state == GTK_SHEET_COLUMN_SELECTED) - sheet->active_cell.row = MIN_VISIBLE_ROW (sheet); return FALSE; + break; } - if (extend_selection) return TRUE; - - gtk_sheet_activate_cell (sheet, sheet->active_cell.row, - sheet->active_cell.col); - return TRUE; } static void -gtk_sheet_size_request (GtkWidget * widget, - GtkRequisition * requisition) +gtk_sheet_size_request (GtkWidget *widget, + GtkRequisition *requisition) { GtkSheet *sheet; - GList *children; - GtkSheetChild *child; - GtkRequisition child_requisition; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); @@ -5875,8 +4311,8 @@ gtk_sheet_size_request (GtkWidget * widget, sheet = GTK_SHEET (widget); - requisition->width = 3*DEFAULT_COLUMN_WIDTH; - requisition->height = 3*DEFAULT_ROW_HEIGHT (widget); + requisition->width = 3 * DEFAULT_COLUMN_WIDTH; + requisition->height = 3 * DEFAULT_ROW_HEIGHT; /* compute the size of the column title area */ if (sheet->column_titles_visible) @@ -5885,21 +4321,12 @@ gtk_sheet_size_request (GtkWidget * widget, /* compute the size of the row title area */ if (sheet->row_titles_visible) requisition->width += sheet->row_title_area.width; - - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - gtk_widget_size_request (child->widget, &child_requisition); - } } static void -gtk_sheet_size_allocate (GtkWidget * widget, - GtkAllocation * allocation) +gtk_sheet_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { GtkSheet *sheet; GtkAllocation sheet_allocation; @@ -5920,22 +4347,11 @@ gtk_sheet_size_allocate (GtkWidget * widget, allocation->width - 2 * border_width, allocation->height - 2 * border_width); - /* use internal allocation structure for all the math - * because it's easier than always subtracting the container - * border width */ - sheet->internal_allocation.x = 0; - sheet->internal_allocation.y = 0; - sheet->internal_allocation.width = allocation->width - 2 * border_width; - sheet->internal_allocation.height = allocation->height - 2 * border_width; - sheet_allocation.x = 0; sheet_allocation.y = 0; sheet_allocation.width = allocation->width - 2 * border_width; sheet_allocation.height = allocation->height - 2 * border_width; - sheet->sheet_window_width = sheet_allocation.width; - sheet->sheet_window_height = sheet_allocation.height; - if (GTK_WIDGET_REALIZED (widget)) gdk_window_move_resize (sheet->sheet_window, sheet_allocation.x, @@ -5946,10 +4362,21 @@ gtk_sheet_size_allocate (GtkWidget * widget, /* position the window which holds the column title buttons */ sheet->column_title_area.x = 0; sheet->column_title_area.y = 0; + sheet->column_title_area.width = sheet_allocation.width ; + + + /* position the window which holds the row title buttons */ + sheet->row_title_area.x = 0; + sheet->row_title_area.y = 0; + sheet->row_title_area.height = sheet_allocation.height; + if (sheet->row_titles_visible) - sheet->column_title_area.x = sheet->row_title_area.width; - sheet->column_title_area.width = sheet_allocation.width - - sheet->column_title_area.x; + sheet->column_title_area.x += sheet->row_title_area.width; + + if (sheet->column_titles_visible) + sheet->row_title_area.y += sheet->column_title_area.height; + + if (GTK_WIDGET_REALIZED (widget) && sheet->column_titles_visible) gdk_window_move_resize (sheet->column_title_window, sheet->column_title_area.x, @@ -5957,19 +4384,6 @@ gtk_sheet_size_allocate (GtkWidget * widget, sheet->column_title_area.width, sheet->column_title_area.height); - sheet->sheet_window_width = sheet_allocation.width; - sheet->sheet_window_height = sheet_allocation.height; - - /* column button allocation */ - size_allocate_column_title_buttons (sheet); - - /* position the window which holds the row title buttons */ - sheet->row_title_area.x = 0; - sheet->row_title_area.y = 0; - if (sheet->column_titles_visible) - sheet->row_title_area.y = sheet->column_title_area.height; - sheet->row_title_area.height = sheet_allocation.height - - sheet->row_title_area.y; if (GTK_WIDGET_REALIZED (widget) && sheet->row_titles_visible) gdk_window_move_resize (sheet->row_title_window, @@ -5978,35 +4392,50 @@ gtk_sheet_size_allocate (GtkWidget * widget, sheet->row_title_area.width, sheet->row_title_area.height); + if (sheet->haxis) + { + gint width = sheet->column_title_area.width; + + if ( sheet->row_titles_visible) + width -= sheet->row_title_area.width; + + g_object_set (sheet->haxis, + "minimum-extent", width, + NULL); + } + + + if (sheet->vaxis) + { + gint height = sheet->row_title_area.height; + + if ( sheet->column_titles_visible) + height -= sheet->column_title_area.height; - /* row button allocation */ - size_allocate_row_title_buttons (sheet); - size_allocate_column_title_buttons (sheet); + g_object_set (sheet->vaxis, + "minimum-extent", height, + NULL); + } - /* re - scale backing pixmap */ - gtk_sheet_make_backing_pixmap (sheet, 0, 0); - gtk_sheet_position_children (sheet); /* set the scrollbars adjustments */ adjust_scrollbars (sheet); } static void -size_allocate_column_title_buttons (GtkSheet * sheet) +draw_column_title_buttons (GtkSheet *sheet) { - gint i; gint x, width; if (!sheet->column_titles_visible) return; if (!GTK_WIDGET_REALIZED (sheet)) return; - width = sheet->sheet_window_width; + gdk_drawable_get_size (sheet->sheet_window, &width, NULL); x = 0; if (sheet->row_titles_visible) { - width -= sheet->row_title_area.width; x = sheet->row_title_area.width; } @@ -6021,8 +4450,8 @@ size_allocate_column_title_buttons (GtkSheet * sheet) sheet->column_title_area.height); } - - if (MAX_VISIBLE_COLUMN (sheet) == xxx_column_count (sheet) - 1) + if (max_visible_column (sheet) == + psppire_axis_unit_count (sheet->haxis) - 1) gdk_window_clear_area (sheet->column_title_window, 0, 0, sheet->column_title_area.width, @@ -6032,26 +4461,24 @@ size_allocate_column_title_buttons (GtkSheet * sheet) size_allocate_global_button (sheet); - for (i = MIN_VISIBLE_COLUMN (sheet); i <= MAX_VISIBLE_COLUMN (sheet); i++) - gtk_sheet_column_title_button_draw (sheet, i); + draw_column_title_buttons_range (sheet, min_visible_column (sheet), + max_visible_column (sheet)); } static void -size_allocate_row_title_buttons (GtkSheet * sheet) +draw_row_title_buttons (GtkSheet *sheet) { - gint i; - gint y, height; + gint y = 0; + gint height; if (!sheet->row_titles_visible) return; if (!GTK_WIDGET_REALIZED (sheet)) return; - height = sheet->sheet_window_height; - y = 0; + gdk_drawable_get_size (sheet->sheet_window, NULL, &height); if (sheet->column_titles_visible) { - height -= sheet->column_title_area.height; y = sheet->column_title_area.height; } @@ -6065,7 +4492,8 @@ size_allocate_row_title_buttons (GtkSheet * sheet) sheet->row_title_area.width, sheet->row_title_area.height); } - if (MAX_VISIBLE_ROW (sheet) == yyy_row_count (sheet)- 1) + + if (max_visible_row (sheet) == psppire_axis_unit_count (sheet->vaxis) - 1) gdk_window_clear_area (sheet->row_title_window, 0, 0, sheet->row_title_area.width, @@ -6075,30 +4503,23 @@ size_allocate_row_title_buttons (GtkSheet * sheet) size_allocate_global_button (sheet); - for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++) - { - if ( i >= yyy_row_count (sheet)) - break; - gtk_sheet_row_title_button_draw (sheet, i); - } + + draw_row_title_buttons_range (sheet, min_visible_row (sheet), + max_visible_row (sheet)); } static void gtk_sheet_size_allocate_entry (GtkSheet *sheet) { - GtkAllocation shentry_allocation; + GtkAllocation entry_alloc; GtkSheetCellAttr attributes = { 0 }; GtkEntry *sheet_entry; - GtkStyle *style = NULL, *previous_style = NULL; - gint row, col; - gint size, max_size, text_size, column_width; - const gchar *text; if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return; - sheet_entry = GTK_ENTRY (gtk_sheet_get_entry (sheet)); + sheet_entry = gtk_sheet_get_entry (sheet); if ( ! gtk_sheet_get_attributes (sheet, sheet->active_cell.row, sheet->active_cell.col, @@ -6107,166 +4528,45 @@ gtk_sheet_size_allocate_entry (GtkSheet *sheet) if ( GTK_WIDGET_REALIZED (sheet->entry_widget) ) { - if (!GTK_WIDGET (sheet_entry)->style) - gtk_widget_ensure_style (GTK_WIDGET (sheet_entry)); - - previous_style = GTK_WIDGET (sheet_entry)->style; + GtkStyle *style = GTK_WIDGET (sheet_entry)->style; - style = gtk_style_copy (previous_style); style->bg[GTK_STATE_NORMAL] = attributes.background; style->fg[GTK_STATE_NORMAL] = attributes.foreground; style->text[GTK_STATE_NORMAL] = attributes.foreground; style->bg[GTK_STATE_ACTIVE] = attributes.background; style->fg[GTK_STATE_ACTIVE] = attributes.foreground; style->text[GTK_STATE_ACTIVE] = attributes.foreground; - - pango_font_description_free (style->font_desc); - g_assert (attributes.font_desc); - style->font_desc = pango_font_description_copy (attributes.font_desc); - - GTK_WIDGET (sheet_entry)->style = style; - gtk_widget_size_request (sheet->entry_widget, NULL); - GTK_WIDGET (sheet_entry)->style = previous_style; - - if (style != previous_style) - { - if (!GTK_IS_ITEM_ENTRY (sheet->entry_widget)) - { - style->bg[GTK_STATE_NORMAL] = previous_style->bg[GTK_STATE_NORMAL]; - style->fg[GTK_STATE_NORMAL] = previous_style->fg[GTK_STATE_NORMAL]; - style->bg[GTK_STATE_ACTIVE] = previous_style->bg[GTK_STATE_ACTIVE]; - style->fg[GTK_STATE_ACTIVE] = previous_style->fg[GTK_STATE_ACTIVE]; - } - gtk_widget_set_style (GTK_WIDGET (sheet_entry), style); - g_object_unref (style); - } } - if (GTK_IS_ITEM_ENTRY (sheet_entry)) - max_size = GTK_ITEM_ENTRY (sheet_entry)->text_max_size; - else - max_size = 0; - - text_size = 0; - text = gtk_entry_get_text (GTK_ENTRY (sheet_entry)); - if (text && strlen (text) > 0) - text_size = STRING_WIDTH (GTK_WIDGET (sheet), attributes.font_desc, text); - - column_width = xxx_column_width (sheet, sheet->active_cell.col); - - size = MIN (text_size, max_size); - size = MAX (size, column_width - 2 * CELLOFFSET); - - row = sheet->active_cell.row; - col = sheet->active_cell.col; - - shentry_allocation.x = COLUMN_LEFT_XPIXEL (sheet, sheet->active_cell.col); - shentry_allocation.y = ROW_TOP_YPIXEL (sheet, sheet->active_cell.row); - shentry_allocation.width = column_width; - shentry_allocation.height = yyy_row_height (sheet, sheet->active_cell.row); - - if (GTK_IS_ITEM_ENTRY (sheet->entry_widget)) - { - shentry_allocation.height -= 2 * CELLOFFSET; - shentry_allocation.y += CELLOFFSET; - shentry_allocation.width = size; - - switch (GTK_ITEM_ENTRY (sheet_entry)->justification) - { - case GTK_JUSTIFY_CENTER: - shentry_allocation.x += column_width / 2 - size / 2; - break; - case GTK_JUSTIFY_RIGHT: - shentry_allocation.x += column_width - size - CELLOFFSET; - break; - case GTK_JUSTIFY_LEFT: - case GTK_JUSTIFY_FILL: - shentry_allocation.x += CELLOFFSET; - break; - } - } + rectangle_from_cell (sheet, sheet->active_cell.row, + sheet->active_cell.col, &entry_alloc); - if (!GTK_IS_ITEM_ENTRY (sheet->entry_widget)) - { - shentry_allocation.x += 2; - shentry_allocation.y += 2; - shentry_allocation.width -= MIN (shentry_allocation.width, 3); - shentry_allocation.height -= MIN (shentry_allocation.height, 3); - } + entry_alloc.width -= BORDER_WIDTH; + entry_alloc.height -= BORDER_WIDTH; + entry_alloc.x += BORDER_WIDTH / 2; + entry_alloc.y += BORDER_WIDTH / 2; - gtk_widget_size_allocate (sheet->entry_widget, &shentry_allocation); - if (previous_style == style) g_object_unref (previous_style); + gtk_widget_set_size_request (sheet->entry_widget, entry_alloc.width, + entry_alloc.height); + gtk_widget_size_allocate (sheet->entry_widget, &entry_alloc); } + +/* Copy the sheet's font to the entry widget */ static void -gtk_sheet_entry_set_max_size (GtkSheet *sheet) +set_entry_widget_font (GtkSheet *sheet) { - gint i; - gint size = 0; - gint sizel = 0, sizer = 0; - gint row, col; - GtkJustification justification; - gchar *s = NULL; - - row = sheet->active_cell.row; - col = sheet->active_cell.col; + GtkRcStyle *style = gtk_widget_get_modifier_style (sheet->entry_widget); - if ( ! GTK_IS_ITEM_ENTRY (sheet->entry_widget) ) - return; - - justification = GTK_ITEM_ENTRY (sheet->entry_widget)->justification; - - switch (justification) - { - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++) - { - if ((s = gtk_sheet_cell_get_text (sheet, row, i))) - { - g_free (s); - break; - } - size +=xxx_column_width (sheet, i); - } - size = MIN (size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL (sheet, col)); - break; - case GTK_JUSTIFY_RIGHT: - for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--) - { - if ((s = gtk_sheet_cell_get_text (sheet, row, i))) - { - g_free (s); - break; - } - size +=xxx_column_width (sheet, i); - } - break; - case GTK_JUSTIFY_CENTER: - for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++) - { - sizer += xxx_column_width (sheet, i); - } - for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--) - { - if ((s = gtk_sheet_cell_get_text (sheet, row, i))) - { - g_free (s); - break; - } - sizel +=xxx_column_width (sheet, i); - } - size = 2 * MIN (sizel, sizer); - break; - } + pango_font_description_free (style->font_desc); + style->font_desc = pango_font_description_copy (GTK_WIDGET (sheet)->style->font_desc); - if (size != 0) - size += xxx_column_width (sheet, col); - GTK_ITEM_ENTRY (sheet->entry_widget)->text_max_size = size; + gtk_widget_modify_style (sheet->entry_widget, style); } + static void create_sheet_entry (GtkSheet *sheet) { @@ -6275,32 +4575,18 @@ create_sheet_entry (GtkSheet *sheet) gtk_widget_unparent (sheet->entry_widget); } - if (sheet->entry_type) - { - sheet->entry_container = g_object_new (sheet->entry_type, NULL); - g_object_ref_sink (sheet->entry_container); - sheet->entry_widget = gtk_sheet_get_entry (sheet); + sheet->entry_widget = g_object_new (sheet->entry_type, NULL); + g_object_ref_sink (sheet->entry_widget); - if ( NULL == sheet->entry_widget) - { - g_warning ("Entry type is %s. It must be GtkEntry subclass, or a widget containing one. " - "Using default", g_type_name (sheet->entry_type)); - g_object_unref (sheet->entry_container); - sheet->entry_widget = sheet->entry_container = gtk_item_entry_new (); - } - else - { - sheet->entry_widget = sheet->entry_container ; - } - } - else + gtk_widget_size_request (sheet->entry_widget, NULL); + + if ( GTK_IS_ENTRY (sheet->entry_widget)) { - sheet->entry_widget = sheet->entry_container = gtk_item_entry_new (); - g_object_ref_sink (sheet->entry_container); + g_object_set (sheet->entry_widget, + "has-frame", FALSE, + NULL); } - gtk_widget_size_request (sheet->entry_widget, NULL); - if (GTK_WIDGET_REALIZED (sheet)) { gtk_widget_set_parent_window (sheet->entry_widget, sheet->sheet_window); @@ -6312,6 +4598,14 @@ create_sheet_entry (GtkSheet *sheet) G_CALLBACK (gtk_sheet_entry_key_press), sheet); + sheet->entry_handler_id = + g_signal_connect (sheet->entry_widget, + "changed", + G_CALLBACK (gtk_sheet_entry_changed), + sheet); + + set_entry_widget_font (sheet); + gtk_widget_show (sheet->entry_widget); } @@ -6327,92 +4621,52 @@ find_entry (GtkWidget *w, gpointer user_data) } } -GtkWidget * + +GtkEntry * gtk_sheet_get_entry (GtkSheet *sheet) { - GtkWidget *parent; - GtkWidget *entry = NULL; - GtkTableChild *table_child; - GtkBoxChild *box_child; - GList *children = NULL; + GtkWidget *w = sheet->entry_widget; g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); g_return_val_if_fail (sheet->entry_widget != NULL, NULL); - if (GTK_IS_ENTRY (sheet->entry_container)) - return (sheet->entry_container); - - parent = sheet->entry_container; - - if (GTK_IS_TABLE (parent)) children = GTK_TABLE (parent)->children; - if (GTK_IS_BOX (parent)) children = GTK_BOX (parent)->children; - - if (GTK_IS_CONTAINER (parent)) + while (! GTK_IS_ENTRY (w)) { - gtk_container_forall (GTK_CONTAINER (parent), find_entry, &entry); - - if (GTK_IS_ENTRY (entry)) - return entry; - } - - if (!children) return NULL; + GtkWidget *entry = NULL; - while (children) - { - if (GTK_IS_TABLE (parent)) - { - table_child = children->data; - entry = table_child->widget; - } - if (GTK_IS_BOX (parent)) + if (GTK_IS_CONTAINER (w)) { - box_child = children->data; - entry = box_child->widget; - } - - if (GTK_IS_ENTRY (entry)) - break; - children = children->next; - } - - - if (!GTK_IS_ENTRY (entry)) return NULL; + gtk_container_forall (GTK_CONTAINER (w), find_entry, &entry); - return (entry); - -} - -GtkWidget * -gtk_sheet_get_entry_widget (GtkSheet *sheet) -{ - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - g_return_val_if_fail (sheet->entry_widget != NULL, NULL); + if (NULL == entry) + break; - return (sheet->entry_widget); + w = entry; + } + } + + return GTK_ENTRY (w); } static void -gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, +draw_button (GtkSheet *sheet, GdkWindow *window, GtkSheetButton *button, gboolean is_sensitive, GdkRectangle allocation) { GtkShadowType shadow_type; gint text_width = 0, text_height = 0; - GtkSheetChild *child = NULL; PangoAlignment align = PANGO_ALIGN_LEFT; gboolean rtl ; gint state = 0; - gint len = 0; - gchar *line = 0; g_return_if_fail (sheet != NULL); g_return_if_fail (button != NULL); + rtl = gtk_widget_get_direction (GTK_WIDGET (sheet)) == GTK_TEXT_DIR_RTL; gdk_window_clear_area (window, @@ -6444,77 +4698,56 @@ gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, if (button->label_visible) { - - text_height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))- 2 * CELLOFFSET; + text_height = DEFAULT_ROW_HEIGHT - + 2 * COLUMN_TITLES_HEIGHT; gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->fg_gc[button->state], &allocation); - gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->white_gc, &allocation); + gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->white_gc, + &allocation); allocation.y += 2 * sheet->button->style->ythickness; - if (button->label && strlen (button->label)>0) { - gchar *words = 0; + PangoRectangle rect; + gchar *line = button->label; + PangoLayout *layout = NULL; - gint real_x = allocation.x, real_y = allocation.y; + gint real_x = allocation.x; + gint real_y = allocation.y; - words = button->label; - line = g_new (gchar, 1); - line[0]='\0'; + layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), line); + pango_layout_get_extents (layout, NULL, &rect); - while (words && *words != '\0') + text_width = PANGO_PIXELS (rect.width); + switch (button->justification) { - if (*words != '\n') - { - len = strlen (line); - line = g_realloc (line, len + 2); - line[len]=*words; - line[len + 1]='\0'; - } - if (*words == '\n' || * (words + 1) == '\0') - { - text_width = STRING_WIDTH (GTK_WIDGET (sheet), GTK_WIDGET (sheet)->style->font_desc, line); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), line); - switch (button->justification) - { - case GTK_JUSTIFY_LEFT: - real_x = allocation.x + CELLOFFSET; - align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; - break; - case GTK_JUSTIFY_RIGHT: - real_x = allocation.x + allocation.width - text_width - CELLOFFSET; - align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; - break; - case GTK_JUSTIFY_CENTER: - default: - real_x = allocation.x + (allocation.width - text_width)/2; - align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; - pango_layout_set_justify (layout, TRUE); - } - pango_layout_set_alignment (layout, align); - gtk_paint_layout (GTK_WIDGET (sheet)->style, - window, - state, - FALSE, - &allocation, - GTK_WIDGET (sheet), - "label", - real_x, real_y, - layout); - g_object_unref (layout); - - real_y += text_height + 2; - - g_free (line); - line = g_new (gchar, 1); - line[0]='\0'; - } - words++; + case GTK_JUSTIFY_LEFT: + real_x = allocation.x + COLUMN_TITLES_HEIGHT; + align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; + break; + case GTK_JUSTIFY_RIGHT: + real_x = allocation.x + allocation.width - text_width - COLUMN_TITLES_HEIGHT; + align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; + break; + case GTK_JUSTIFY_CENTER: + default: + real_x = allocation.x + (allocation.width - text_width)/2; + align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; + pango_layout_set_justify (layout, TRUE); } - g_free (line); + pango_layout_set_alignment (layout, align); + gtk_paint_layout (GTK_WIDGET (sheet)->style, + window, + state, + FALSE, + &allocation, + GTK_WIDGET (sheet), + "label", + real_x, real_y, + layout); + g_object_unref (layout); } gdk_gc_set_clip_rectangle (GTK_WIDGET (sheet)->style->fg_gc[button->state], @@ -6523,119 +4756,106 @@ gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, } - if ((child = button->child) && (child->widget)) - { - child->x = allocation.x; - child->y = allocation.y; - - child->x += (allocation.width - child->widget->requisition.width) / 2; - child->y += (allocation.height - child->widget->requisition.height) / 2; - allocation.x = child->x; - allocation.y = child->y; - allocation.width = child->widget->requisition.width; - allocation.height = child->widget->requisition.height; - - allocation.x = child->x; - allocation.y = child->y; - - gtk_widget_set_state (child->widget, button->state); - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && - GTK_WIDGET_MAPPED (child->widget)) - { - gtk_widget_size_allocate (child->widget, - &allocation); - gtk_widget_queue_draw (child->widget); - } - } - gtk_sheet_button_free (button); } -/* COLUMN value of - 1 indicates that the area to the right of the rightmost - button should be redrawn */ +/* Draw the column title buttons FIRST through to LAST */ static void -gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column) +draw_column_title_buttons_range (GtkSheet *sheet, gint first, gint last) { - GdkWindow *window = NULL; - GdkRectangle allocation; - - gboolean is_sensitive = FALSE; - + GdkRectangle rect; + gint col; if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (column >= 0 && ! xxx_column_is_visible (sheet, column)) return; - if (column >= 0 && !sheet->column_titles_visible) return; - if (column >= 0 && column < MIN_VISIBLE_COLUMN (sheet)) return; - if (column >= 0 && column > MAX_VISIBLE_COLUMN (sheet)) return; + if (!sheet->column_titles_visible) return; - window = sheet->column_title_window; - allocation.y = 0; - allocation.height = sheet->column_title_area.height; + g_return_if_fail (first >= min_visible_column (sheet)); + g_return_if_fail (last <= max_visible_column (sheet)); - if ( column == -1 ) - { - const gint cols = xxx_column_count (sheet) ; - allocation.x = COLUMN_LEFT_XPIXEL (sheet, cols - 1) - ; - allocation.width = sheet->column_title_area.width - + sheet->column_title_area.x - - allocation.x; + rect.y = 0; + rect.height = sheet->column_title_area.height; + rect.x = psppire_axis_pixel_start (sheet->haxis, first) + CELL_SPACING; + rect.width = psppire_axis_pixel_start (sheet->haxis, last) + CELL_SPACING + + psppire_axis_unit_size (sheet->haxis, last); - gdk_window_clear_area (window, - allocation.x, allocation.y, - allocation.width, allocation.height); - } - else - { - GtkSheetButton *button = xxx_column_button (sheet, column); - allocation.x = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING; - if (sheet->row_titles_visible) - allocation.x -= sheet->row_title_area.width; + rect.x -= sheet->hadjustment->value; + + minimize_int (&rect.width, sheet->column_title_area.width); + maximize_int (&rect.x, 0); - allocation.width = xxx_column_width (sheet, column); + gdk_window_begin_paint_rect (sheet->column_title_window, &rect); - is_sensitive = xxx_column_is_sensitive (sheet, column); - gtk_sheet_button_draw (sheet, window, button, - is_sensitive, allocation); + for (col = first ; col <= last ; ++col) + { + GdkRectangle allocation; + gboolean is_sensitive = FALSE; - /* FIXME: Not freeing this button is correct (sort of), - because in PSPP the model always returns a static copy */ + GtkSheetButton * + button = g_sheet_model_get_column_button (sheet->model, col); + allocation.y = 0; + allocation.x = psppire_axis_pixel_start (sheet->haxis, col) + + CELL_SPACING; + allocation.x -= sheet->hadjustment->value; - /* gtk_sheet_button_free (button); */ + allocation.height = sheet->column_title_area.height; + allocation.width = psppire_axis_unit_size (sheet->haxis, col); + is_sensitive = g_sheet_model_get_column_sensitivity (sheet->model, col); + draw_button (sheet, sheet->column_title_window, + button, is_sensitive, allocation); } + + gdk_window_end_paint (sheet->column_title_window); } + static void -gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row) +draw_row_title_buttons_range (GtkSheet *sheet, gint first, gint last) { - GdkWindow *window = NULL; - GdkRectangle allocation; - GtkSheetButton *button = NULL; - gboolean is_sensitive = FALSE; + GdkRectangle rect; + gint row; + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; + if (!sheet->row_titles_visible) return; - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; + g_return_if_fail (first >= min_visible_row (sheet)); + g_return_if_fail (last <= max_visible_row (sheet)); - if (row >= 0 && !yyy_row_is_visible (sheet, row)) return; - if (row >= 0 && !sheet->row_titles_visible) return; - if (row >= 0 && row < MIN_VISIBLE_ROW (sheet)) return; - if (row >= 0 && row > MAX_VISIBLE_ROW (sheet)) return; + rect.x = 0; + rect.width = sheet->row_title_area.width; + rect.y = psppire_axis_pixel_start (sheet->vaxis, first) + CELL_SPACING; + rect.height = psppire_axis_pixel_start (sheet->vaxis, last) + CELL_SPACING + + psppire_axis_unit_size (sheet->vaxis, last); + rect.y -= sheet->vadjustment->value; - window = sheet->row_title_window; - button = yyy_row_button (sheet, row); - allocation.x = 0; - allocation.y = ROW_TOP_YPIXEL (sheet, row) + CELL_SPACING; - if (sheet->column_titles_visible) - allocation.y -= sheet->column_title_area.height; - allocation.width = sheet->row_title_area.width; - allocation.height = yyy_row_height (sheet, row); - is_sensitive = yyy_row_is_sensitive (sheet, row); + 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; + + GtkSheetButton *button = + g_sheet_model_get_row_button (sheet->model, row); + allocation.x = 0; + allocation.y = psppire_axis_pixel_start (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 = g_sheet_model_get_row_sensitivity (sheet->model, row); + + draw_button (sheet, sheet->row_title_window, + button, is_sensitive, allocation); + } - gtk_sheet_button_draw (sheet, window, button, is_sensitive, allocation); + gdk_window_end_paint (sheet->row_title_window); } /* SCROLLBARS @@ -6646,292 +4866,190 @@ gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row) * hadjustment_value_changed */ static void -adjust_scrollbars (GtkSheet * sheet) +adjust_scrollbars (GtkSheet *sheet) { - if (sheet->vadjustment) - { - sheet->vadjustment->page_size = sheet->sheet_window_height; - sheet->vadjustment->page_increment = sheet->sheet_window_height / 2; - sheet->vadjustment->step_increment = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); - sheet->vadjustment->lower = 0; - sheet->vadjustment->upper = SHEET_HEIGHT (sheet) + 80; - g_signal_emit_by_name (sheet->vadjustment, "changed"); - - } + gint width, height; - if (sheet->hadjustment) - { - sheet->hadjustment->page_size = sheet->sheet_window_width; - sheet->hadjustment->page_increment = sheet->sheet_window_width / 2; - sheet->hadjustment->step_increment = DEFAULT_COLUMN_WIDTH; - sheet->hadjustment->lower = 0; - sheet->hadjustment->upper = SHEET_WIDTH (sheet)+ 80; - g_signal_emit_by_name (sheet->hadjustment, "changed"); + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + return; - } -} + gdk_drawable_get_size (sheet->sheet_window, &width, &height); -static void -vadjustment_value_changed (GtkAdjustment * adjustment, - gpointer data) -{ - GtkSheet *sheet; - gint diff, value, old_value; - gint row, new_row; - gint y = 0; + if ( sheet->row_titles_visible) + width -= sheet->row_title_area.width; - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (GTK_IS_SHEET (data)); + if (sheet->column_titles_visible) + height -= sheet->column_title_area.height; - sheet = GTK_SHEET (data); + if (sheet->vadjustment) + { + glong last_row = psppire_axis_unit_count (sheet->vaxis) - 1; - if (GTK_SHEET_IS_FROZEN (sheet)) return; + sheet->vadjustment->step_increment = + ROWS_PER_STEP * + psppire_axis_unit_size (sheet->vaxis, last_row); - row = ROW_FROM_YPIXEL (sheet, CELL_SPACING); + sheet->vadjustment->page_increment = + height - + sheet->column_title_area.height - + psppire_axis_unit_size (sheet->vaxis, last_row); - old_value = - sheet->voffset; - new_row = g_sheet_row_pixel_to_row (sheet->row_geometry, - adjustment->value, sheet); - y = g_sheet_row_start_pixel (sheet->row_geometry, new_row, sheet); + sheet->vadjustment->upper = + psppire_axis_pixel_start (sheet->vaxis, last_row) + + + psppire_axis_unit_size (sheet->vaxis, last_row) + ; - if (adjustment->value > sheet->old_vadjustment && sheet->old_vadjustment > 0. && - yyy_row_height (sheet, row) > sheet->vadjustment->step_increment) - { - /* This avoids embarrassing twitching */ - if (row == new_row && row != yyy_row_count (sheet) - 1 && - adjustment->value - sheet->old_vadjustment >= - sheet->vadjustment->step_increment && - new_row + 1 != MIN_VISIBLE_ROW (sheet)) - { - new_row +=1; - y = y+yyy_row_height (sheet, row); - } - } + sheet->vadjustment->lower = 0; + sheet->vadjustment->page_size = height; - /* Negative old_adjustment enforces the redraw, otherwise avoid - spureous redraw */ - if (sheet->old_vadjustment >= 0. && row == new_row) - { - sheet->old_vadjustment = sheet->vadjustment->value; - return; + g_signal_emit_by_name (sheet->vadjustment, "changed"); } - sheet->old_vadjustment = sheet->vadjustment->value; - adjustment->value = y; - - - if (new_row == 0) - { - sheet->vadjustment->step_increment = yyy_row_height (sheet, 0); - } - else + if (sheet->hadjustment) { - sheet->vadjustment->step_increment = - MIN (yyy_row_height (sheet, new_row), yyy_row_height (sheet, new_row - 1)); - } - - sheet->vadjustment->value = adjustment->value; + gint last_col; + sheet->hadjustment->step_increment = 1; - value = adjustment->value; - - if (value >= - sheet->voffset) - { - /* scroll down */ - diff = value + sheet->voffset; - } - else - { - /* scroll up */ - diff = - sheet->voffset - value; - } + sheet->hadjustment->page_increment = width; - sheet->voffset = - value; + last_col = psppire_axis_unit_count (sheet->haxis) - 1; - if (GTK_WIDGET_REALIZED (sheet->entry_widget) && - sheet->state == GTK_SHEET_NORMAL && - sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 && - !gtk_sheet_cell_isvisible (sheet, sheet->active_cell.row, - sheet->active_cell.col)) - { - const gchar *text; + sheet->hadjustment->upper = + psppire_axis_pixel_start (sheet->haxis, last_col) + + + psppire_axis_unit_size (sheet->haxis, last_col) + ; - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); + sheet->hadjustment->lower = 0; + sheet->hadjustment->page_size = width; - if (!text || strlen (text) == 0) - gtk_sheet_cell_clear (sheet, - sheet->active_cell.row, - sheet->active_cell.col); - gtk_widget_unmap (sheet->entry_widget); + g_signal_emit_by_name (sheet->hadjustment, "changed"); } - - gtk_sheet_position_children (sheet); - - gtk_sheet_range_draw (sheet, NULL); - size_allocate_row_title_buttons (sheet); - size_allocate_global_button (sheet); } static void -hadjustment_value_changed (GtkAdjustment * adjustment, +vadjustment_value_changed (GtkAdjustment *adjustment, gpointer data) { - GtkSheet *sheet; - gint i, diff, value, old_value; - gint column, new_column; - gint x = 0; + GdkRegion *region; + GtkSheet *sheet = GTK_SHEET (data); g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (GTK_IS_SHEET (data)); - sheet = GTK_SHEET (data); - - if (GTK_SHEET_IS_FROZEN (sheet)) return; + if ( ! GTK_WIDGET_REALIZED (sheet)) return; - column = COLUMN_FROM_XPIXEL (sheet, CELL_SPACING); - old_value = - sheet->hoffset; + gtk_widget_hide (sheet->entry_widget); - for (i = 0; i < xxx_column_count (sheet); i++) - { - if (xxx_column_is_visible (sheet, i)) x += xxx_column_width (sheet, i); - if (x > adjustment->value) break; - } - x -= xxx_column_width (sheet, i); - new_column = i; + region = + gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window)); - if (adjustment->value > sheet->old_hadjustment && sheet->old_hadjustment > 0 && - xxx_column_width (sheet, i) > sheet->hadjustment->step_increment) - { - /* This avoids embarrassing twitching */ - if (column == new_column && column != xxx_column_count (sheet) - 1 && - adjustment->value - sheet->old_hadjustment >= - sheet->hadjustment->step_increment && - new_column + 1 != MIN_VISIBLE_COLUMN (sheet)) - { - new_column += 1; - x += xxx_column_width (sheet, column); - } - } + gdk_window_begin_paint_region (sheet->sheet_window, region); - /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */ - if (sheet->old_hadjustment >= 0. && new_column == column) - { - sheet->old_hadjustment = sheet->hadjustment->value; - return; - } - sheet->old_hadjustment = sheet->hadjustment->value; - adjustment->value = x; + gtk_sheet_range_draw (sheet, NULL); + draw_row_title_buttons (sheet); + // size_allocate_global_button (sheet); + gtk_sheet_draw_active_cell (sheet); - if (new_column == 0) - { - sheet->hadjustment->step_increment = xxx_column_width (sheet, 0); - } - else - { - sheet->hadjustment->step_increment = - MIN (xxx_column_width (sheet, new_column), xxx_column_width (sheet, new_column - 1)); - } + gdk_window_end_paint (sheet->sheet_window); +} - sheet->hadjustment->value = adjustment->value; +static void +hadjustment_value_changed (GtkAdjustment *adjustment, + gpointer data) +{ + GdkRegion *region; + GtkSheet *sheet = GTK_SHEET (data); - value = adjustment->value; + g_return_if_fail (adjustment != NULL); - if (value >= - sheet->hoffset) - { - /* scroll right */ - diff = value + sheet->hoffset; - } - else - { - /* scroll left */ - diff = - sheet->hoffset - value; - } + if ( ! GTK_WIDGET_REALIZED (sheet)) return; - sheet->hoffset = - value; - if (GTK_WIDGET_REALIZED (sheet->entry_widget) && - sheet->state == GTK_SHEET_NORMAL && - sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 && - !gtk_sheet_cell_isvisible (sheet, sheet->active_cell.row, - sheet->active_cell.col)) - { - const gchar *text; + gtk_widget_hide (sheet->entry_widget); - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); - if (!text || strlen (text) == 0) - gtk_sheet_cell_clear (sheet, - sheet->active_cell.row, - sheet->active_cell.col); - gtk_widget_unmap (sheet->entry_widget); - } + region = + gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->sheet_window)); - gtk_sheet_position_children (sheet); + gdk_window_begin_paint_region (sheet->sheet_window, region); gtk_sheet_range_draw (sheet, NULL); - size_allocate_column_title_buttons (sheet); + draw_column_title_buttons (sheet); + // size_allocate_global_button (sheet); + + gtk_sheet_draw_active_cell (sheet); + + gdk_window_end_paint (sheet->sheet_window); } /* COLUMN RESIZING */ static void -draw_xor_vline (GtkSheet * sheet) +draw_xor_vline (GtkSheet *sheet) { - GtkWidget *widget; + gint height; + gint xpos = sheet->x_drag; + gdk_drawable_get_size (sheet->sheet_window, + NULL, &height); - g_return_if_fail (sheet != NULL); - widget = GTK_WIDGET (sheet); + if (sheet->row_titles_visible) + xpos += sheet->row_title_area.width; - gdk_draw_line (widget->window, sheet->xor_gc, - sheet->x_drag, + gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc, + xpos, sheet->column_title_area.height, - sheet->x_drag, - sheet->sheet_window_height + 1); + xpos, + height + CELL_SPACING); } /* ROW RESIZING */ static void -draw_xor_hline (GtkSheet * sheet) +draw_xor_hline (GtkSheet *sheet) + { - GtkWidget *widget; + gint width; + gint ypos = sheet->y_drag; - g_return_if_fail (sheet != NULL); + gdk_drawable_get_size (sheet->sheet_window, + &width, NULL); - widget = GTK_WIDGET (sheet); - gdk_draw_line (widget->window, sheet->xor_gc, - sheet->row_title_area.width, - sheet->y_drag, + if (sheet->column_titles_visible) + ypos += sheet->column_title_area.height; - sheet->sheet_window_width + 1, - sheet->y_drag); + 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 (GtkSheet *sheet, GtkSheetRange range) { - gint i; + gint i = 0; GdkRectangle clip_area, area; GdkGCValues values; - area.x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - area.y = ROW_TOP_YPIXEL (sheet, range.row0); - area.width = COLUMN_LEFT_XPIXEL (sheet, range.coli)- area.x+ - xxx_column_width (sheet, range.coli); - area.height = ROW_TOP_YPIXEL (sheet, range.rowi)- area.y+ - yyy_row_height (sheet, range.rowi); + area.x = psppire_axis_pixel_start (sheet->haxis, range.col0); + area.y = psppire_axis_pixel_start (sheet->vaxis, range.row0); + area.width = psppire_axis_pixel_start (sheet->haxis, range.coli)- area.x+ + psppire_axis_unit_size (sheet->haxis, range.coli); + area.height = psppire_axis_pixel_start (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; - clip_area.width = sheet->sheet_window_width; - clip_area.height = sheet->sheet_window_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; @@ -6958,50 +5076,42 @@ draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) gdk_gc_set_clip_rectangle (sheet->xor_gc, &clip_area); - for (i = -1; i <= 1; ++i) - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - FALSE, - area.x + i, area.y + i, - area.width - 2 * i, area.height - 2 * i); + gdk_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + FALSE, + area.x + i, area.y + i, + area.width - 2 * i, area.height - 2 * i); gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL); gdk_gc_set_foreground (sheet->xor_gc, &values.foreground); - } /* this function returns the new width of the column being resized given - * the column and x position of the cursor; the x cursor position is passed - * in as a pointer and automaticaly corrected if it's beyond min / max limits */ + * the COLUMN and X position of the cursor; the x cursor position is passed + * in as a pointer and automaticaly corrected if it's outside the acceptable + * range */ static guint -new_column_width (GtkSheet * sheet, - gint column, - gint * x) +new_column_width (GtkSheet *sheet, gint column, gint *x) { - gint cx, width; - guint min_width; + gint left_pos = psppire_axis_pixel_start (sheet->haxis, column) + - sheet->hadjustment->value; - cx = *x; + gint width = *x - left_pos; - min_width = sheet->column_requisition; - - /* you can't shrink a column to less than its minimum width */ - if (cx < COLUMN_LEFT_XPIXEL (sheet, column) + min_width) + if ( width < sheet->column_requisition) { - *x = cx = COLUMN_LEFT_XPIXEL (sheet, column) + min_width; + width = sheet->column_requisition; + *x = left_pos + width; } - /* calculate new column width making sure it doesn't end up - * less than the minimum width */ - width = cx - COLUMN_LEFT_XPIXEL (sheet, column); - if (width < min_width) - width = min_width; +#if AXIS_TRANSITION + g_sheet_column_set_width (sheet->column_geometry, column, width); +#endif - xxx_set_column_width (sheet, column, width); - size_allocate_column_title_buttons (sheet); + draw_column_title_buttons (sheet); return width; } @@ -7010,37 +5120,37 @@ new_column_width (GtkSheet * sheet, * the row and y position of the cursor; the y cursor position is passed * in as a pointer and automaticaly corrected if it's beyond min / max limits */ static guint -new_row_height (GtkSheet * sheet, - gint row, - gint * y) +new_row_height (GtkSheet *sheet, gint row, gint *y) { - gint cy, height; + gint height; guint min_height; - cy = *y; + gint cy = *y; min_height = sheet->row_requisition; /* you can't shrink a row to less than its minimum height */ - if (cy < ROW_TOP_YPIXEL (sheet, row) + min_height) + if (cy < psppire_axis_pixel_start (sheet->vaxis, row) + min_height) { - *y = cy = ROW_TOP_YPIXEL (sheet, row) + min_height; + *y = cy = psppire_axis_pixel_start (sheet->vaxis, row) + min_height; } /* calculate new row height making sure it doesn't end up * less than the minimum height */ - height = (cy - ROW_TOP_YPIXEL (sheet, row)); + height = (cy - psppire_axis_pixel_start (sheet->vaxis, row)); if (height < min_height) height = min_height; - yyy_set_row_height (sheet, row, height); - size_allocate_row_title_buttons (sheet); +#if AXIS_TRANSITION + g_sheet_row_set_height (sheet->row_geometry, row, height); +#endif + draw_row_title_buttons (sheet); return height; } static void -gtk_sheet_set_column_width (GtkSheet * sheet, +gtk_sheet_set_column_width (GtkSheet *sheet, gint column, guint width) { @@ -7049,367 +5159,109 @@ gtk_sheet_set_column_width (GtkSheet * sheet, g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column < 0 || column >= xxx_column_count (sheet)) - return; - - gtk_sheet_column_size_request (sheet, column, &min_width); - if (width < min_width) return; - - xxx_set_column_width (sheet, column, width); - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet)) - { - size_allocate_column_title_buttons (sheet); - adjust_scrollbars (sheet); - gtk_sheet_size_allocate_entry (sheet); - gtk_sheet_range_draw (sheet, NULL); - } - - g_signal_emit (sheet, sheet_signals[CHANGED], 0, -1, column); -} - - - -void -gtk_sheet_set_row_height (GtkSheet * sheet, - gint row, - guint height) -{ - guint min_height; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - if (row < 0 || row >= yyy_row_count (sheet)) - return; - - gtk_sheet_row_size_request (sheet, row, &min_height); - if (height < min_height) return; - - yyy_set_row_height (sheet, row, height); - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet)) - { - size_allocate_row_title_buttons (sheet); - adjust_scrollbars (sheet); - gtk_sheet_size_allocate_entry (sheet); - gtk_sheet_range_draw (sheet, NULL); - } - - g_signal_emit (sheet, sheet_signals[CHANGED], 0, row, - 1); -} -gboolean -gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col, - GtkSheetCellAttr *attributes) -{ - const GdkColor *fg, *bg; - const GtkJustification *j ; - const PangoFontDescription *font_desc ; - const GtkSheetCellBorder *border ; - - g_return_val_if_fail (sheet != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); - - if (row < 0 || col < 0) return FALSE; - - init_attributes (sheet, col, attributes); - - if ( !sheet->model) - return FALSE; - - attributes->is_editable = g_sheet_model_is_editable (sheet->model, row, col); - attributes->is_visible = g_sheet_model_is_visible (sheet->model, row, col); - - fg = g_sheet_model_get_foreground (sheet->model, row, col); - if ( fg ) - attributes->foreground = *fg; - - bg = g_sheet_model_get_background (sheet->model, row, col); - if ( bg ) - attributes->background = *bg; - - j = g_sheet_model_get_justification (sheet->model, row, col); - if (j) attributes->justification = *j; - - font_desc = g_sheet_model_get_font_desc (sheet->model, row, col); - if ( font_desc ) attributes->font_desc = font_desc; - - border = g_sheet_model_get_cell_border (sheet->model, row, col); - - if ( border ) attributes->border = *border; - - return TRUE; -} - -static void -init_attributes (const GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes) -{ - /* DEFAULT VALUES */ - attributes->foreground = GTK_WIDGET (sheet)->style->black; - attributes->background = sheet->bg_color; - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - GdkColormap *colormap; - colormap = gdk_colormap_get_system (); - attributes->background = sheet->bg_color; - } - attributes->justification = xxx_column_justification (sheet, col); - attributes->border.width = 0; - attributes->border.line_style = GDK_LINE_SOLID; - attributes->border.cap_style = GDK_CAP_NOT_LAST; - attributes->border.join_style = GDK_JOIN_MITER; - attributes->border.mask = 0; - attributes->border.color = GTK_WIDGET (sheet)->style->black; - attributes->is_editable = TRUE; - attributes->is_visible = TRUE; - attributes->font_desc = GTK_WIDGET (sheet)->style->font_desc; -} - - -/******************************************************************** - * Container Functions: - * gtk_sheet_add - * gtk_sheet_put - * gtk_sheet_attach - * gtk_sheet_remove - * gtk_sheet_move_child - * gtk_sheet_position_child - * gtk_sheet_position_children - * gtk_sheet_realize_child - * gtk_sheet_get_child_at - ********************************************************************/ - -GtkSheetChild * -gtk_sheet_put (GtkSheet *sheet, GtkWidget *child, gint x, gint y) -{ - GtkRequisition child_requisition; - GtkSheetChild *child_info; - - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - g_return_val_if_fail (child != NULL, NULL); - g_return_val_if_fail (child->parent == NULL, NULL); - - child_info = g_new (GtkSheetChild, 1); - child_info->widget = child; - child_info->x = x; - child_info->y = y; - child_info->attached_to_cell = FALSE; - child_info->floating = TRUE; - child_info->xpadding = child_info->ypadding = 0; - child_info->xexpand = child_info->yexpand = FALSE; - child_info->xshrink = child_info->yshrink = FALSE; - child_info->xfill = child_info->yfill = FALSE; - - sheet->children = g_list_append (sheet->children, child_info); - - gtk_widget_set_parent (child, GTK_WIDGET (sheet)); - - gtk_widget_size_request (child, &child_requisition); - - if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet))) - { - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && - (!GTK_WIDGET_REALIZED (child) || GTK_WIDGET_NO_WINDOW (child))) - gtk_sheet_realize_child (sheet, child_info); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) && - !GTK_WIDGET_MAPPED (child)) - gtk_widget_map (child); - } - - gtk_sheet_position_child (sheet, child_info); - - /* This will avoid drawing on the titles */ - - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) - { - if (sheet->row_titles_visible) - gdk_window_show (sheet->row_title_window); - if (sheet->column_titles_visible) - gdk_window_show (sheet->column_title_window); - } + if (column < 0 || column >= psppire_axis_unit_count (sheet->haxis)) + return; - return (child_info); -} + gtk_sheet_column_size_request (sheet, column, &min_width); + if (width < min_width) return; -void -gtk_sheet_attach_floating (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) -{ - GdkRectangle area; - GtkSheetChild *child; +#if AXIS_TRANSITION + g_sheet_column_set_width (sheet->column_geometry, column, width); +#endif - if (row < 0 || col < 0) + if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) { - gtk_sheet_button_attach (sheet, widget, row, col); - return; + draw_column_title_buttons (sheet); + adjust_scrollbars (sheet); + gtk_sheet_size_allocate_entry (sheet); + gtk_sheet_range_draw (sheet, NULL); } - - gtk_sheet_get_cell_area (sheet, row, col, &area); - child = gtk_sheet_put (sheet, widget, area.x, area.y); - child->attached_to_cell = TRUE; - child->row = row; - child->col = col; } -void -gtk_sheet_attach_default (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) -{ - if (row < 0 || col < 0) - { - gtk_sheet_button_attach (sheet, widget, row, col); - return; - } - gtk_sheet_attach (sheet, widget, row, col, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); -} -void -gtk_sheet_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col, - gint xoptions, - gint yoptions, - gint xpadding, - gint ypadding) +static void +gtk_sheet_set_row_height (GtkSheet *sheet, + gint row, + guint height) { - GdkRectangle area; - GtkSheetChild *child = NULL; - - if (row < 0 || col < 0) - { - gtk_sheet_button_attach (sheet, widget, row, col); - return; - } + guint min_height; - child = g_new0 (GtkSheetChild, 1); - child->attached_to_cell = TRUE; - child->floating = FALSE; - child->widget = widget; - child->row = row; - child->col = col; - child->xpadding = xpadding; - child->ypadding = ypadding; - child->xexpand = (xoptions & GTK_EXPAND) != 0; - child->yexpand = (yoptions & GTK_EXPAND) != 0; - child->xshrink = (xoptions & GTK_SHRINK) != 0; - child->yshrink = (yoptions & GTK_SHRINK) != 0; - child->xfill = (xoptions & GTK_FILL) != 0; - child->yfill = (yoptions & GTK_FILL) != 0; - - sheet->children = g_list_append (sheet->children, child); - - gtk_sheet_get_cell_area (sheet, row, col, &area); - - child->x = area.x + child->xpadding; - child->y = area.y + child->ypadding; - - if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet))) - { - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && - (!GTK_WIDGET_REALIZED (widget) || GTK_WIDGET_NO_WINDOW (widget))) - gtk_sheet_realize_child (sheet, child); + g_return_if_fail (sheet != NULL); + g_return_if_fail (GTK_IS_SHEET (sheet)); - if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) && - !GTK_WIDGET_MAPPED (widget)) - gtk_widget_map (widget); - } + if (row < 0 || row >= psppire_axis_unit_count (sheet->vaxis)) + return; - gtk_sheet_position_child (sheet, child); + gtk_sheet_row_size_request (sheet, row, &min_height); + if (height < min_height) return; - /* This will avoid drawing on the titles */ +#if AXIS_TRANSITION + g_sheet_row_set_height (sheet->row_geometry, row, height); +#endif - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) + if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) ) { - if (GTK_SHEET_ROW_TITLES_VISIBLE (sheet)) - gdk_window_show (sheet->row_title_window); - if (GTK_SHEET_COL_TITLES_VISIBLE (sheet)) - gdk_window_show (sheet->column_title_window); + draw_row_title_buttons (sheet); + adjust_scrollbars (sheet); + gtk_sheet_size_allocate_entry (sheet); + gtk_sheet_range_draw (sheet, NULL); } - } -void -gtk_sheet_button_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) +gboolean +gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col, + GtkSheetCellAttr *attr) { - GtkSheetButton *button = 0; - GtkSheetChild *child; - GtkRequisition button_requisition; - - if (row >= 0 && col >= 0) return; - if (row < 0 && col < 0) return; + GdkColor *fg, *bg; + const GtkJustification *j ; + const GtkSheetCellBorder *border ; + GdkColormap *colormap; - child = g_new (GtkSheetChild, 1); - child->widget = widget; - child->x = 0; - child->y = 0; - child->attached_to_cell = TRUE; - child->floating = FALSE; - child->row = row; - child->col = col; - child->xpadding = child->ypadding = 0; - child->xshrink = child->yshrink = FALSE; - child->xfill = child->yfill = FALSE; + g_return_val_if_fail (sheet != NULL, FALSE); + g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); + if (row < 0 || col < 0) return FALSE; - sheet->children = g_list_append (sheet->children, child); + attr->foreground = GTK_WIDGET (sheet)->style->black; + attr->background = sheet->color[BG_COLOR]; - gtk_sheet_button_size_request (sheet, button, &button_requisition); + 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; + attr->is_editable = g_sheet_model_is_editable (sheet->model, row, col); - if (GTK_WIDGET_VISIBLE (GTK_WIDGET (sheet))) + colormap = gtk_widget_get_colormap (GTK_WIDGET (sheet)); + fg = g_sheet_model_get_foreground (sheet->model, row, col); + if ( fg ) { - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && - (!GTK_WIDGET_REALIZED (widget) || GTK_WIDGET_NO_WINDOW (widget))) - gtk_sheet_realize_child (sheet, child); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) && - !GTK_WIDGET_MAPPED (widget)) - gtk_widget_map (widget); + gdk_colormap_alloc_color (colormap, fg, TRUE, TRUE); + attr->foreground = *fg; } - if (row == -1) size_allocate_column_title_buttons (sheet); - if (col == -1) size_allocate_row_title_buttons (sheet); - -} + bg = g_sheet_model_get_background (sheet->model, row, col); + if ( bg ) + { + gdk_colormap_alloc_color (colormap, bg, TRUE, TRUE); + attr->background = *bg; + } -static void -label_size_request (GtkSheet *sheet, gchar *label, GtkRequisition *req) -{ - gchar *words; - gchar word[1000]; - gint n = 0; - gint row_height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)) - 2 * CELLOFFSET + 2; + attr->justification = + g_sheet_model_get_column_justification (sheet->model, col); - req->height = 0; - req->width = 0; - words = label; + j = g_sheet_model_get_justification (sheet->model, row, col); + if (j) + attr->justification = *j; - while (words && *words != '\0') - { - if (*words == '\n' || * (words + 1) == '\0') - { - req->height += row_height; + border = g_sheet_model_get_cell_border (sheet->model, row, col); - word[n] = '\0'; - req->width = MAX (req->width, STRING_WIDTH (GTK_WIDGET (sheet), GTK_WIDGET (sheet)->style->font_desc, word)); - n = 0; - } - else - { - word[n++] = *words; - } - words++; - } + if ( border ) attr->border = *border; - if (n > 0) req->height -= 2; + return TRUE; } static void @@ -7420,31 +5272,12 @@ gtk_sheet_button_size_request (GtkSheet *sheet, GtkRequisition requisition; GtkRequisition label_requisition; - if (gtk_sheet_autoresize (sheet) && button->label && strlen (button->label) > 0) - { - label_size_request (sheet, button->label, &label_requisition); - label_requisition.width += 2 * CELLOFFSET; - label_requisition.height += 2 * CELLOFFSET; - } - else - { - label_requisition.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); - label_requisition.width = COLUMN_MIN_WIDTH; - } + label_requisition.height = DEFAULT_ROW_HEIGHT; + label_requisition.width = COLUMN_MIN_WIDTH; + + requisition.height = DEFAULT_ROW_HEIGHT; + requisition.width = COLUMN_MIN_WIDTH; - if (button->child) - { - gtk_widget_size_request (button->child->widget, &requisition); - requisition.width += 2 * button->child->xpadding; - requisition.height += 2 * button->child->ypadding; - requisition.width += 2 * sheet->button->style->xthickness; - requisition.height += 2 * sheet->button->style->ythickness; - } - else - { - requisition.height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); - requisition.width = COLUMN_MIN_WIDTH; - } *button_requisition = requisition; button_requisition->width = MAX (requisition.width, label_requisition.width); @@ -7458,31 +5291,14 @@ gtk_sheet_row_size_request (GtkSheet *sheet, guint *requisition) { GtkRequisition button_requisition; - GList *children; gtk_sheet_button_size_request (sheet, - yyy_row_button (sheet, row), + g_sheet_model_get_row_button (sheet->model, row), &button_requisition); *requisition = button_requisition.height; - children = sheet->children; - while (children) - { - GtkSheetChild *child = (GtkSheetChild *)children->data; - GtkRequisition child_requisition; - - if (child->attached_to_cell && child->row == row && child->col != -1 && !child->floating && !child->yshrink) - { - gtk_widget_get_child_requisition (child->widget, &child_requisition); - - if (child_requisition.height + 2 * child->ypadding > *requisition) - *requisition = child_requisition.height + 2 * child->ypadding; - } - children = children->next; - } - - sheet->row_requisition = * requisition; + sheet->row_requisition = *requisition; } static void @@ -7491,8 +5307,8 @@ gtk_sheet_column_size_request (GtkSheet *sheet, guint *requisition) { GtkRequisition button_requisition; - GList *children; - GtkSheetButton *button = xxx_column_button (sheet, col); + + GtkSheetButton *button = g_sheet_model_get_column_button (sheet->model, col); gtk_sheet_button_size_request (sheet, button, @@ -7502,157 +5318,9 @@ gtk_sheet_column_size_request (GtkSheet *sheet, *requisition = button_requisition.width; - children = sheet->children; - while (children) - { - GtkSheetChild *child = (GtkSheetChild *)children->data; - GtkRequisition child_requisition; - - if (child->attached_to_cell && child->col == col && child->row != -1 && !child->floating && !child->xshrink) - { - gtk_widget_get_child_requisition (child->widget, &child_requisition); - - if (child_requisition.width + 2 * child->xpadding > *requisition) - *requisition = child_requisition.width + 2 * child->xpadding; - } - children = children->next; - } - sheet->column_requisition = *requisition; } -void -gtk_sheet_move_child (GtkSheet *sheet, GtkWidget *widget, gint x, gint y) -{ - GtkSheetChild *child; - GList *children; - - g_return_if_fail (sheet != NULL); - g_return_if_fail (GTK_IS_SHEET (sheet)); - - children = sheet->children; - while (children) - { - child = children->data; - - if (child->widget == widget) - { - child->x = x; - child->y = y; - child->row = ROW_FROM_YPIXEL (sheet, y); - child->col = COLUMN_FROM_XPIXEL (sheet, x); - gtk_sheet_position_child (sheet, child); - return; - } - - children = children->next; - } - - g_warning ("Widget must be a GtkSheet child"); - -} - -static void -gtk_sheet_position_child (GtkSheet *sheet, GtkSheetChild *child) -{ - GtkRequisition child_requisition; - GtkAllocation child_allocation; - gint xoffset = 0; - gint yoffset = 0; - gint x = 0, y = 0; - GdkRectangle area; - - gtk_widget_get_child_requisition (child->widget, &child_requisition); - - if (sheet->column_titles_visible) - yoffset = sheet->column_title_area.height; - - if (sheet->row_titles_visible) - xoffset = sheet->row_title_area.width; - - if (child->attached_to_cell) - { - gtk_sheet_get_cell_area (sheet, child->row, child->col, &area); - child->x = area.x + child->xpadding; - child->y = area.y + child->ypadding; - - if (!child->floating) - { - if (child_requisition.width + 2 * child->xpadding <= xxx_column_width (sheet, child->col)) - { - if (child->xfill) - { - child_requisition.width = child_allocation.width = xxx_column_width (sheet, child->col) - 2 * child->xpadding; - } - else - { - if (child->xexpand) - { - child->x = area.x + xxx_column_width (sheet, child->col) / 2 - - child_requisition.width / 2; - } - child_allocation.width = child_requisition.width; - } - } - else - { - if (!child->xshrink) - { - gtk_sheet_set_column_width (sheet, child->col, child_requisition.width + 2 * child->xpadding); - } - child_allocation.width = xxx_column_width (sheet, child->col) - 2 * child->xpadding; - } - - if (child_requisition.height + - 2 * child->ypadding <= yyy_row_height (sheet, child->row)) - { - if (child->yfill) - { - child_requisition.height = child_allocation.height = - yyy_row_height (sheet, child->row) - 2 * child->ypadding; - } - else - { - if (child->yexpand) - { - child->y = area.y + yyy_row_height (sheet, child->row) / 2 - - child_requisition.height / 2; - } - child_allocation.height = child_requisition.height; - } - } - else - { - if (!child->yshrink) - { - gtk_sheet_set_row_height (sheet, child->row, child_requisition.height + 2 * child->ypadding); - } - child_allocation.height = yyy_row_height (sheet, child->row) - - 2 * child->ypadding; - } - } - else - { - child_allocation.width = child_requisition.width; - child_allocation.height = child_requisition.height; - } - - x = child_allocation.x = child->x + xoffset; - y = child_allocation.y = child->y + yoffset; - } - else - { - x = child_allocation.x = child->x + sheet->hoffset + xoffset; - x = child_allocation.x = child->x + xoffset; - y = child_allocation.y = child->y + sheet->voffset + yoffset; - y = child_allocation.y = child->y + yoffset; - child_allocation.width = child_requisition.width; - child_allocation.height = child_requisition.height; - } - - gtk_widget_size_allocate (child->widget, &child_allocation); - gtk_widget_queue_draw (child->widget); -} static void gtk_sheet_forall (GtkContainer *container, @@ -7660,165 +5328,17 @@ gtk_sheet_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data) { - GtkSheet *sheet; - GtkSheetChild *child; - GList *children; + GtkSheet *sheet = GTK_SHEET (container); - g_return_if_fail (GTK_IS_SHEET (container)); g_return_if_fail (callback != NULL); - sheet = GTK_SHEET (container); - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - (* callback) (child->widget, callback_data); - } - if (sheet->button && sheet->button->parent) (* callback) (sheet->button, callback_data); - if (sheet->entry_container && GTK_IS_CONTAINER (sheet->entry_container)) - (* callback) (sheet->entry_container, callback_data); -} - - -static void -gtk_sheet_position_children (GtkSheet *sheet) -{ - GList *children; - GtkSheetChild *child; - - children = sheet->children; - - while (children) - { - child = (GtkSheetChild *)children->data; - - if (child->col != -1 && child->row != -1) - gtk_sheet_position_child (sheet, child); - - if (child->row == -1) - { - if (child->col < MIN_VISIBLE_COLUMN (sheet) || - child->col > MAX_VISIBLE_COLUMN (sheet)) - gtk_sheet_child_hide (child); - else - gtk_sheet_child_show (child); - } - if (child->col == -1) - { - if (child->row < MIN_VISIBLE_ROW (sheet) || - child->row > MAX_VISIBLE_ROW (sheet)) - gtk_sheet_child_hide (child); - else - gtk_sheet_child_show (child); - } - - children = children->next; - } -} - -static void -gtk_sheet_remove (GtkContainer *container, GtkWidget *widget) -{ - GtkSheet *sheet; - GList *children; - GtkSheetChild *child = 0; - - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_SHEET (container)); - - sheet = GTK_SHEET (container); - - children = sheet->children; - - while (children) - { - child = (GtkSheetChild *)children->data; - - if (child->widget == widget) break; - - children = children->next; - } - - if (children) - { - gtk_widget_unparent (widget); - child->widget = NULL; - - sheet->children = g_list_remove_link (sheet->children, children); - g_list_free_1 (children); - g_free (child); - } - - gtk_widget_unparent (sheet->button); -} - -static void -gtk_sheet_realize_child (GtkSheet *sheet, GtkSheetChild *child) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (sheet); - - if (GTK_WIDGET_REALIZED (widget)) - { - if (child->row == -1) - gtk_widget_set_parent_window (child->widget, sheet->column_title_window); - else if (child->col == -1) - gtk_widget_set_parent_window (child->widget, sheet->row_title_window); - else - gtk_widget_set_parent_window (child->widget, sheet->sheet_window); - } - - gtk_widget_set_parent (child->widget, widget); -} - - - -GtkSheetChild * -gtk_sheet_get_child_at (GtkSheet *sheet, gint row, gint col) -{ - GList *children; - GtkSheetChild *child = 0; - - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); - - children = sheet->children; - - while (children) - { - child = (GtkSheetChild *)children->data; - - if (child->attached_to_cell) - if (child->row == row && child->col == col) break; - - children = children->next; - } - - if (children) return child; - - return NULL; -} - -static void -gtk_sheet_child_hide (GtkSheetChild *child) -{ - g_return_if_fail (child != NULL); - gtk_widget_hide (child->widget); + if (sheet->entry_widget && GTK_IS_CONTAINER (sheet->entry_widget)) + (* callback) (sheet->entry_widget, callback_data); } -static void -gtk_sheet_child_show (GtkSheetChild *child) -{ - g_return_if_fail (child != NULL); - - gtk_widget_show (child->widget); -} GSheetModel * gtk_sheet_get_model (const GtkSheet *sheet) @@ -7837,14 +5357,13 @@ gtk_sheet_button_new (void) button->state = GTK_STATE_NORMAL; button->label = NULL; button->label_visible = TRUE; - button->child = NULL; button->justification = GTK_JUSTIFY_FILL; return button; } -inline void +void gtk_sheet_button_free (GtkSheetButton *button) { if (!button) return ; @@ -7853,15 +5372,26 @@ gtk_sheet_button_free (GtkSheetButton *button) g_free (button); } +static void +append_cell_text (GString *string, const GtkSheet *sheet, gint r, gint c) +{ + gchar *celltext = gtk_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 GtkSheet *sheet) { - gchar *celltext = NULL; gint r, c; GString *string; - if ( !gtk_sheet_range_isvisible (sheet, sheet->range)) + if ( !gtk_sheet_range_isvisible (sheet, &sheet->range)) return NULL; string = g_string_sized_new (80); @@ -7870,16 +5400,12 @@ range_to_text (const GtkSheet *sheet) { for (c = sheet->range.col0; c < sheet->range.coli; ++c) { - celltext = gtk_sheet_cell_get_text (sheet, r, c); - g_string_append (string, celltext); + append_cell_text (string, sheet, r, c); g_string_append (string, "\t"); - g_free (celltext); } - celltext = gtk_sheet_cell_get_text (sheet, r, c); - g_string_append (string, celltext); + append_cell_text (string, sheet, r, c); if ( r < sheet->range.rowi) g_string_append (string, "\n"); - g_free (celltext); } return string; @@ -7888,11 +5414,10 @@ range_to_text (const GtkSheet *sheet) static GString * range_to_html (const GtkSheet *sheet) { - gchar *celltext = NULL; gint r, c; GString *string; - if ( !gtk_sheet_range_isvisible (sheet, sheet->range)) + if ( !gtk_sheet_range_isvisible (sheet, &sheet->range)) return NULL; string = g_string_sized_new (480); @@ -7906,10 +5431,8 @@ range_to_html (const GtkSheet *sheet) for (c = sheet->range.col0; c <= sheet->range.coli; ++c) { g_string_append (string, ""); - celltext = gtk_sheet_cell_get_text (sheet, r, c); - g_string_append (string, celltext); + append_cell_text (string, sheet, r, c); g_string_append (string, "\n"); - g_free (celltext); } g_string_append (string, "\n"); } @@ -7985,7 +5508,7 @@ gtk_sheet_update_primary_selection (GtkSheet *sheet) clipboard = gtk_widget_get_clipboard (GTK_WIDGET (sheet), GDK_SELECTION_PRIMARY); - if (gtk_sheet_range_isvisible (sheet, sheet->range)) + if (gtk_sheet_range_isvisible (sheet, &sheet->range)) { if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets), @@ -7999,4 +5522,3 @@ gtk_sheet_update_primary_selection (GtkSheet *sheet) gtk_clipboard_clear (clipboard); } } -