From: John Darrington Date: Tue, 11 Nov 2008 04:39:40 +0000 (+0900) Subject: Merge branch 'master' into rewrite-sheet X-Git-Tag: v0.7.1~175 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3ac5a8af9c449072c7e872ca70a78c1755ae309;hp=0172359b97d990c1eacb3a9a0003c7142ba0b520;p=pspp-builds.git Merge branch 'master' into rewrite-sheet Conflicts: lib/gtksheet/automake.mk po/en_GB.po --- diff --git a/lib/gtksheet/automake.mk b/lib/gtksheet/automake.mk index b2838260..c5a32962 100644 --- a/lib/gtksheet/automake.mk +++ b/lib/gtksheet/automake.mk @@ -25,8 +25,12 @@ lib_gtksheet_libgtksheet_a_SOURCES = \ lib/gtksheet/gtkextra-sheet.h \ lib/gtksheet/gtkitementry.h \ lib/gtksheet/gtkitementry.c \ + lib/gtksheet/gtkmarshalers.c \ + lib/gtksheet/gtkmarshalers.h \ lib/gtksheet/gtksheet.c \ - lib/gtksheet/gtksheet.h + lib/gtksheet/gtksheet.h \ + lib/gtksheet/gtkxpaned.c \ + lib/gtksheet/gtkxpaned.h EXTRA_DIST += lib/gtksheet/OChangeLog \ lib/gtksheet/README diff --git a/lib/gtksheet/gsheet-column-iface.h b/lib/gtksheet/gsheet-column-iface.h index 5503393a..4ad1d3fc 100644 --- a/lib/gtksheet/gsheet-column-iface.h +++ b/lib/gtksheet/gsheet-column-iface.h @@ -76,8 +76,7 @@ struct _GSheetColumnIface gboolean (*get_button_visibility)(const GSheetColumn *geo, glong col); - const GtkSheetChild * (*get_button_child)(const GSheetColumn *geo, - glong col); + GtkJustification * (*get_button_justification)(const GSheetColumn *geo, glong col); }; diff --git a/lib/gtksheet/gsheet-hetero-column.c b/lib/gtksheet/gsheet-hetero-column.c index ecc06cc5..1344b839 100644 --- a/lib/gtksheet/gsheet-hetero-column.c +++ b/lib/gtksheet/gsheet-hetero-column.c @@ -165,7 +165,6 @@ g_sheet_hetero_column_class_init (GSheetHeteroColumnClass *class) object_class->finalize = g_sheet_hetero_column_finalize; default_button.label=NULL; - default_button.child=NULL; default_button.state=GTK_STATE_NORMAL; default_button.justification=GTK_JUSTIFY_CENTER; default_button.label_visible = TRUE; diff --git a/lib/gtksheet/gsheet-row-iface.c b/lib/gtksheet/gsheet-row-iface.c index 1512737f..81bc56bb 100644 --- a/lib/gtksheet/gsheet-row-iface.c +++ b/lib/gtksheet/gsheet-row-iface.c @@ -96,7 +96,6 @@ g_sheet_row_base_init (gpointer g_class) default_button.state = GTK_STATE_NORMAL; default_button.label = NULL; default_button.label_visible = TRUE; - default_button.child = NULL; default_button.justification = GTK_JUSTIFY_FILL; initialized = TRUE; diff --git a/lib/gtksheet/gsheet-row-iface.h b/lib/gtksheet/gsheet-row-iface.h index 921f3699..ded46671 100644 --- a/lib/gtksheet/gsheet-row-iface.h +++ b/lib/gtksheet/gsheet-row-iface.h @@ -70,9 +70,6 @@ struct _GSheetRowIface gboolean (*get_button_visibility) (const GSheetRow *geo, glong row); - const GtkSheetChild * (*get_button_child) (const GSheetRow *geo, - glong row); - guint (*top_ypixel) (const GSheetRow *geo, glong row); glong (*pixel_to_row) (const GSheetRow *geo, guint pixel); }; diff --git a/lib/gtksheet/gtkextra-sheet.h b/lib/gtksheet/gtkextra-sheet.h index 0a5fb70f..ae13c6a9 100644 --- a/lib/gtksheet/gtkextra-sheet.h +++ b/lib/gtksheet/gtkextra-sheet.h @@ -32,34 +32,12 @@ struct _GtkSheet ; typedef struct _GtkSheet GtkSheet; -struct _GtkSheetChild -{ - GtkWidget *widget; - gint x,y ; - gboolean attached_to_cell; - gboolean floating; - gint row, col; - guint16 xpadding; - guint16 ypadding; - gboolean xexpand; - gboolean yexpand; - gboolean xshrink; - gboolean yshrink; - gboolean xfill; - gboolean yfill; -}; - -typedef struct _GtkSheetChild GtkSheetChild; - - - struct _GtkSheetButton { GtkStateType state; gchar *label; gboolean label_visible; - GtkSheetChild *child; GtkJustification justification; }; diff --git a/lib/gtksheet/gtkmarshalers.c b/lib/gtksheet/gtkmarshalers.c new file mode 100644 index 00000000..2b939840 --- /dev/null +++ b/lib/gtksheet/gtkmarshalers.c @@ -0,0 +1,137 @@ +/******************************************************************************* +**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 +** 10 20 30 40 50 60 70 80 +** +** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+ +** Copyright (C) 2005-2006 Mirco "MacSlow" Müller +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License as published by the Free Software Foundation; either +** version 2.1 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public +** License along with this library; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +** +** GtkXPaned is based on GtkPaned which was done by... +** +** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald" +** +** and later modified by... +** +** "the GTK+ Team and others 1997-2000" +** +*******************************************************************************/ + +#include "gtkmarshalers.h" + +/* lazy copied some marshalers copied from gtk+-2.6.10/gtk/gtkmarshalers.c */ +void gtk_marshal_BOOLEAN__BOOLEAN (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN) (gpointer data1, + gboolean arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOOLEAN callback; + register GCClosure* cc = (GCClosure*) closure; + register gpointer data1; + register gpointer data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + + callback = (GMarshalFunc_BOOLEAN__BOOLEAN) (marshal_data ? marshal_data : cc->callback); + v_return = callback (data1, g_marshal_value_peek_boolean (param_values + 1), data2); + g_value_set_boolean (return_value, v_return); +} + +void gtk_marshal_BOOLEAN__ENUM (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__ENUM) (gpointer data1, + gint arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__ENUM callback; + register GCClosure* cc = (GCClosure*) closure; + register gpointer data1; + register gpointer data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + + callback = (GMarshalFunc_BOOLEAN__ENUM) (marshal_data ? marshal_data : cc->callback); + v_return = callback (data1, g_marshal_value_peek_enum (param_values + 1), data2); + g_value_set_boolean (return_value, v_return); +} + +void gtk_marshal_BOOLEAN__VOID (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_BOOLEAN__VOID callback; + register GCClosure* cc = (GCClosure*) closure; + register gpointer data1; + register gpointer data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + v_return = callback (data1, data2); + g_value_set_boolean (return_value, v_return); +} diff --git a/lib/gtksheet/gtkmarshalers.h b/lib/gtksheet/gtkmarshalers.h new file mode 100644 index 00000000..0fce94f9 --- /dev/null +++ b/lib/gtksheet/gtkmarshalers.h @@ -0,0 +1,63 @@ +/******************************************************************************* +**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 +** 10 20 30 40 50 60 70 80 +** +** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+ +** Copyright (C) 2005-2006 Mirco "MacSlow" Müller +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License as published by the Free Software Foundation; either +** version 2.1 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public +** License along with this library; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +** +** GtkXPaned is based on GtkPaned which was done by... +** +** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald" +** +** and later modified by... +** +** "the GTK+ Team and others 1997-2000" +** +*******************************************************************************/ + +#ifndef GTK_MARSHALERS_H +#define GTK_MARSHALERS_H + +#include + +/* lazy copied some marshalers copied from gtk+-2.6.10/gtk/gtkmarshalers.h */ +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long + +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int + +void gtk_marshal_BOOLEAN__BOOLEAN (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data); + +void gtk_marshal_BOOLEAN__ENUM (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data); + +void gtk_marshal_BOOLEAN__VOID (GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data); + +#endif /* GTK_MARSHALERS_H */ diff --git a/lib/gtksheet/gtksheet.c b/lib/gtksheet/gtksheet.c index 942b0233..ec8e3840 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,12 +46,8 @@ #include #include #include -#include #include #include -#include -#include -#include #include #include #include @@ -72,20 +61,18 @@ /* 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_REDRAW_PENDING = 1 << 0, + 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) @@ -94,10 +81,10 @@ enum #define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING) #define CELL_SPACING 1 -#define DRAG_WIDTH 6 + #define TIMEOUT_HOVER 300 #define COLUMN_MIN_WIDTH 10 -#define CELLOFFSET 4 +#define COLUMN_TITLES_HEIGHT 4 #define DEFAULT_COLUMN_WIDTH 80 static void gtk_sheet_update_primary_selection (GtkSheet *sheet); @@ -106,7 +93,10 @@ static void gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column); static void gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row); -static gboolean gtk_sheet_cell_empty (const GtkSheet *sheet, gint row, gint col); +static gboolean gtk_sheet_cell_empty (const GtkSheet *, gint, gint); + +static void destroy_hover_window (GtkSheetHoverTitle *); +static GtkSheetHoverTitle *create_hover_window (void); static inline void dispose_string (const GtkSheet *sheet, gchar *text) @@ -137,7 +127,7 @@ guint DEFAULT_ROW_HEIGHT (GtkWidget *widget) pango_font_metrics_unref (metrics); - return PANGO_PIXELS (val) + 2 * CELLOFFSET; + return PANGO_PIXELS (val) + 2 * COLUMN_TITLES_HEIGHT; } } @@ -192,306 +182,85 @@ guint DEFAULT_FONT_DESCENT (GtkWidget *widget) } -static gint -yyy_row_is_visible (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_visibility (row_geo, row); -} - - -static gint -yyy_row_is_sensitive (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_sensitivity (row_geo, row); -} - - - -static inline gint -yyy_row_count (const GtkSheet *sheet) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_row_count (row_geo); -} - -static inline gint -yyy_row_height (const GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_height (row_geo, row); -} - -static gint -yyy_row_top_ypixel (const GtkSheet *sheet, gint row) -{ - GSheetRow *geo = sheet->row_geometry; - - gint y = g_sheet_row_start_pixel (geo, row); - - if ( sheet->column_titles_visible ) - y += sheet->column_title_area.height; - - return y; -} - - /* Return 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); -} - - -/* gives the top pixel of the given row in context of - * the sheet's voffset */ -static inline gint -ROW_TOP_YPIXEL (const GtkSheet *sheet, gint row) -{ - return (sheet->voffset + yyy_row_top_ypixel (sheet, row)); -} - - -/* returns the row index from a y pixel location in the - * context of the sheet's voffset */ -static inline gint -ROW_FROM_YPIXEL (const GtkSheet *sheet, gint y) -{ - return (yyy_row_ypixel_to_row (sheet, y)); -} - -static inline GtkSheetButton * -xxx_column_button (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - if ( col < 0 ) return NULL ; - - return g_sheet_column_get_button (col_geo, col); -} - - -static inline gint -xxx_column_left_xpixel (const GtkSheet *sheet, gint col) -{ - 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; -} - -static inline gint -xxx_column_width (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_width (col_geo, col); -} - - -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); -} - -static inline void -xxx_column_set_left_column (GtkSheet *sheet, gint col, gint i) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - g_sheet_column_set_left_text_column (col_geo, col, i); -} - -static inline gint -xxx_column_left_column (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - 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) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - g_sheet_column_set_right_text_column (col_geo, col, i); -} - -static inline gint -xxx_column_right_column (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_right_text_column (col_geo, col); -} + if (y < 0) return -1; -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); + return g_sheet_row_pixel_to_row (geo, y); } -static inline gint -xxx_column_is_visible (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; - - return g_sheet_column_get_visibility (col_geo, col); -} +#define MIN_VISIBLE_ROW(sheet) yyy_row_ypixel_to_row (sheet, sheet->vadjustment->value) -static inline gint -xxx_column_is_sensitive (const GtkSheet *sheet, gint col) -{ - GSheetColumn *col_geo = sheet->column_geometry; +#define MAX_VISIBLE_ROW(sheet) \ + yyy_row_ypixel_to_row (sheet, sheet->vadjustment->value + sheet->vadjustment->page_size) - return g_sheet_column_get_sensitivity (col_geo, col); -} +#define MIN_VISIBLE_COLUMN(sheet) COLUMN_FROM_XPIXEL (sheet, sheet->hadjustment->value) +#define MAX_VISIBLE_COLUMN(sheet) \ + COLUMN_FROM_XPIXEL (sheet, sheet->hadjustment->value + sheet->hadjustment->page_size) /* 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 g_sheet_column_start_pixel (sheet->column_geometry, ncol); } -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 */ +/* returns the column index from a x pixel location */ static inline gint -COLUMN_FROM_XPIXEL (const GtkSheet * sheet, - gint x) +COLUMN_FROM_XPIXEL (const GtkSheet *sheet, gint x) { - gint i, cx; - - cx = sheet->hoffset; - if ( sheet->row_titles_visible ) - cx += sheet->row_title_area.width; + gint i; + gint cx = 0; - if (x < cx) return 0; - for (i = 0; i < xxx_column_count (sheet); i++) + if (x < 0) return -1; + for (i = 0; + i < g_sheet_column_get_column_count (sheet->column_geometry); i++) { - if (x >= cx && x <= (cx + xxx_column_width (sheet, i)) && - xxx_column_is_visible (sheet, i)) + if (x >= cx && + x <= (cx + g_sheet_column_get_width (sheet->column_geometry, i)) && + g_sheet_column_get_visibility (sheet->column_geometry, i)) return i; - if ( xxx_column_is_visible (sheet, i)) - cx += xxx_column_width (sheet, i); + if ( g_sheet_column_get_visibility (sheet->column_geometry, i)) + cx += g_sheet_column_get_width (sheet->column_geometry, i); } /* no match */ - return xxx_column_count (sheet) - 1; -} - -/* returns the total height of the sheet */ -static inline gint SHEET_HEIGHT (GtkSheet *sheet) -{ - const gint n_rows = yyy_row_count (sheet); - - return yyy_row_top_ypixel (sheet, n_rows - 1) + - yyy_row_height (sheet, n_rows - 1); -} - - -static inline GtkSheetButton * -yyy_row_button (GtkSheet *sheet, gint row) -{ - GSheetRow *row_geo = sheet->row_geometry; - - return g_sheet_row_get_button (row_geo, row); + return g_sheet_column_get_column_count (sheet->column_geometry) - 1; } +/* 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) +static gboolean +on_column_boundary (const GtkSheet *sheet, gint x, gint *column) { - if ( sheet->row_geometry ) - g_sheet_row_set_height (sheet->row_geometry, row, height); -} + gint col; + x += sheet->hadjustment->value; + col = COLUMN_FROM_XPIXEL (sheet, x); -/* returns the total width of the sheet */ -static inline gint SHEET_WIDTH (GtkSheet *sheet) + if ( COLUMN_FROM_XPIXEL (sheet, x - DRAG_WIDTH / 2) < col ) { - 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; + *column = col - 1; + return TRUE; } -#define MIN_VISIBLE_ROW(sheet) \ - ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1) - -#define MAX_VISIBLE_ROW(sheet) \ - ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1) - -#define MIN_VISIBLE_COLUMN(sheet) \ - COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1) - -#define MAX_VISIBLE_COLUMN(sheet) \ - COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width) - - - -static inline gboolean -POSSIBLE_XDRAG (const GtkSheet *sheet, gint x, gint *drag_column) -{ - gint column, xdrag; - - column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_column = column; - - xdrag = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING; - if (x <= xdrag + DRAG_WIDTH / 2 && column != 0) + if ( 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; + 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; } @@ -499,22 +268,23 @@ static inline gboolean POSSIBLE_YDRAG (const GtkSheet *sheet, gint y, gint *drag_row) { gint row, ydrag; - row = ROW_FROM_YPIXEL (sheet, y); + + y += sheet->vadjustment->value; + row = yyy_row_ypixel_to_row (sheet, y); *drag_row = row; - ydrag = ROW_TOP_YPIXEL (sheet, row)+CELL_SPACING; + ydrag = g_sheet_row_start_pixel (sheet->row_geometry, row) + CELL_SPACING; if (y <= ydrag + DRAG_WIDTH / 2 && row != 0) { - while (!yyy_row_is_visible (sheet, row - 1) && row > 0) row--; + while (!g_sheet_row_get_visibility (sheet->row_geometry, row - 1) && row > 0) row--; *drag_row = row - 1; - return yyy_row_is_sensitive (sheet, row - 1); + return g_sheet_row_get_sensitivity (sheet->row_geometry, row - 1); } - ydrag +=yyy_row_height (sheet, row); + ydrag += g_sheet_row_get_height (sheet->row_geometry, row); if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) - return yyy_row_is_sensitive (sheet, row); - + return g_sheet_row_get_sensitivity (sheet->row_geometry, row); return FALSE; } @@ -531,20 +301,20 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, return FALSE; *drag_column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_row = ROW_FROM_YPIXEL (sheet, y); + *drag_row = yyy_row_ypixel_to_row (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) + g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli) + DRAG_WIDTH / 2) { - ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.row0); + ydrag = g_sheet_row_start_pixel (sheet->row_geometry, 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 = g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.rowi) + + g_sheet_row_get_height (sheet->row_geometry, sheet->range.rowi); if (y >= ydrag - DRAG_WIDTH / 2 && y <= ydrag + DRAG_WIDTH / 2) { *drag_row = sheet->range.rowi; @@ -552,9 +322,9 @@ 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 >= g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.row0) - DRAG_WIDTH / 2 && + y <= g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.rowi) + + g_sheet_row_get_height (sheet->row_geometry, sheet->range.rowi) + DRAG_WIDTH / 2) { xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.col0); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) @@ -563,7 +333,7 @@ POSSIBLE_DRAG (const GtkSheet *sheet, gint x, gint y, return TRUE; } xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli) + - xxx_column_width (sheet, sheet->range.coli); + g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli); if (x >= xdrag - DRAG_WIDTH / 2 && x <= xdrag + DRAG_WIDTH / 2) { *drag_column = sheet->range.coli; @@ -586,19 +356,19 @@ POSSIBLE_RESIZE (const GtkSheet *sheet, gint x, gint y, return FALSE; xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->range.coli)+ - xxx_column_width (sheet, sheet->range.coli); + g_sheet_column_get_width (sheet->column_geometry, sheet->range.coli); - ydrag = ROW_TOP_YPIXEL (sheet, sheet->range.rowi)+ - yyy_row_height (sheet, sheet->range.rowi); + ydrag = g_sheet_row_start_pixel (sheet->row_geometry, sheet->range.rowi) + + g_sheet_row_get_height (sheet->row_geometry, sheet->range.rowi); if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - ydrag = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet)); + ydrag = g_sheet_row_start_pixel (sheet->row_geometry, MIN_VISIBLE_ROW (sheet)); if (sheet->state == GTK_SHEET_ROW_SELECTED) xdrag = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet)); *drag_column = COLUMN_FROM_XPIXEL (sheet, x); - *drag_row = ROW_FROM_YPIXEL (sheet, y); + *drag_row = yyy_row_ypixel_to_row (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; @@ -633,6 +403,8 @@ 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, @@ -680,9 +452,6 @@ 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 */ @@ -701,8 +470,8 @@ static void gtk_sheet_click_cell (GtkSheet *sheet, /* Backing Pixmap */ -static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet, - guint width, guint height); +static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet); + static void gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, GtkSheetRange range); /* Scrollbars */ @@ -748,7 +517,8 @@ static void gtk_sheet_button_size_request (GtkSheet *sheet, GtkRequisition *requisition); /* Attributes routines */ -static void init_attributes (const GtkSheet *sheet, gint col, +static void init_attributes (const GtkSheet *sheet, + gint col, GtkSheetCellAttr *attributes); @@ -761,16 +531,6 @@ static void gtk_sheet_real_cell_clear (GtkSheet *sheet, 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); @@ -826,8 +586,9 @@ 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; @@ -872,7 +633,8 @@ gtk_sheet_range_get_type (void) } -static void column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data); +static void column_titles_changed (GtkWidget *w, gint first, gint n_columns, + gpointer data); /* Properties */ enum @@ -968,8 +730,8 @@ gtk_sheet_class_init (GtkSheetClass * klass) GParamSpec *col_geo_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); @@ -1176,7 +938,7 @@ gtk_sheet_class_init (GtkSheetClass * klass) 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; @@ -1226,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; @@ -1252,11 +1016,8 @@ gtk_sheet_init (GtkSheet *sheet) sheet->column_geometry = NULL; sheet->row_geometry = NULL; - sheet->children = 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); @@ -1296,25 +1057,16 @@ gtk_sheet_init (GtkSheet *sheet) sheet->entry_container = NULL; 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; @@ -1357,8 +1109,8 @@ 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 = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + range.rowi = g_sheet_row_get_row_count (sheet->row_geometry) - 1; adjust_scrollbars (sheet); @@ -1389,8 +1141,8 @@ 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 = g_sheet_row_get_row_count (sheet->row_geometry) - 1; + range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; adjust_scrollbars (sheet); @@ -1535,10 +1287,9 @@ column_titles_changed (GtkWidget *w, gint first, gint n_columns, gpointer data) if ( n_columns == -1 ) { extremity = TRUE; - n_columns = xxx_column_count (sheet) - 1 ; + n_columns = g_sheet_column_get_column_count (sheet->column_geometry) - 1 ; } - if (!GTK_SHEET_IS_FROZEN (sheet)) { gint i; for ( i = first ; i <= first + n_columns ; ++i ) @@ -1590,7 +1341,6 @@ gtk_sheet_show_grid (GtkSheet *sheet, gboolean show) sheet->show_grid = show; - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); } @@ -1617,7 +1367,6 @@ gtk_sheet_set_background (GtkSheet *sheet, GdkColor *color) else sheet->bg_color = *color; - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); } @@ -1635,7 +1384,6 @@ gtk_sheet_set_grid (GtkSheet *sheet, GdkColor *color) else sheet->grid_color = *color; - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); } @@ -1645,7 +1393,7 @@ 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); + return g_sheet_column_get_column_count (sheet->column_geometry); } guint @@ -1654,16 +1402,7 @@ 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) -{ - g_return_val_if_fail (sheet != NULL, 0); - g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); - - return (sheet->state); + return g_sheet_row_get_row_count (sheet->row_geometry); } void @@ -1710,9 +1449,9 @@ gtk_sheet_autoresize_column (GtkSheet *sheet, gint column) g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); - if (column >= xxx_column_count (sheet) || column < 0) return; + if (column >= g_sheet_column_get_column_count (sheet->column_geometry) || column < 0) return; - for (row = 0; row < yyy_row_count (sheet); row++) + for (row = 0; row < g_sheet_row_get_row_count (sheet->row_geometry); row++) { gchar *text = gtk_sheet_cell_get_text (sheet, row, column); if (text && strlen (text) > 0) @@ -1725,14 +1464,14 @@ gtk_sheet_autoresize_column (GtkSheet *sheet, gint column) gint width = STRING_WIDTH (GTK_WIDGET (sheet), attributes.font_desc, text) - + 2 * CELLOFFSET + attributes.border.width; + + 2 * COLUMN_TITLES_HEIGHT + attributes.border.width; text_width = MAX (text_width, width); } } dispose_string (sheet, text); } - if (text_width > xxx_column_width (sheet, column) ) + if (text_width > g_sheet_column_get_width (sheet->column_geometry, column) ) { gtk_sheet_set_column_width (sheet, column, text_width); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_REDRAW_PENDING); @@ -1778,51 +1517,6 @@ gtk_sheet_justify_entry (GtkSheet *sheet) } - -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) { @@ -1832,7 +1526,6 @@ gtk_sheet_set_row_titles_width (GtkSheet *sheet, guint width) adjust_scrollbars (sheet); - sheet->old_hadjustment = -1.; if (sheet->hadjustment) g_signal_emit_by_name (sheet->hadjustment, "value_changed"); @@ -1848,7 +1541,6 @@ gtk_sheet_set_column_titles_height (GtkSheet *sheet, guint height) adjust_scrollbars (sheet); - sheet->old_vadjustment = -1.; if (sheet->vadjustment) g_signal_emit_by_name (sheet->vadjustment, "value_changed"); @@ -1858,15 +1550,13 @@ gtk_sheet_set_column_titles_height (GtkSheet *sheet, guint height) 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, @@ -1874,20 +1564,8 @@ gtk_sheet_show_column_titles (GtkSheet *sheet) 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); - } - sheet->old_vadjustment = -1.; if (sheet->vadjustment) g_signal_emit_by_name (sheet->vadjustment, "value_changed"); @@ -1898,8 +1576,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; @@ -1914,22 +1590,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"); @@ -1939,8 +1602,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; @@ -1952,20 +1613,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"); @@ -1974,53 +1624,26 @@ 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; -} void gtk_sheet_moveto (GtkSheet *sheet, @@ -2039,9 +1662,9 @@ gtk_sheet_moveto (GtkSheet *sheet, g_return_if_fail (sheet->hadjustment != NULL); g_return_if_fail (sheet->vadjustment != NULL); - if (row < 0 || row >= yyy_row_count (sheet)) + if (row < 0 || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; - if (column < 0 || column >= xxx_column_count (sheet)) + if (column < 0 || column >= g_sheet_column_get_column_count (sheet->column_geometry)) return; height = sheet->sheet_window_height; @@ -2050,9 +1673,9 @@ gtk_sheet_moveto (GtkSheet *sheet, /* adjust vertical scrollbar */ if (row >= 0 && row_align >= 0.0) { - y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset + y = g_sheet_row_start_pixel (sheet->row_geometry, row) - (gint) ( row_align * height + (1.0 - row_align) - * yyy_row_height (sheet, row)); + * g_sheet_row_get_height (sheet->row_geometry, row)); /* This forces the sheet to scroll when you don't see the entire cell */ min_row = row; @@ -2061,8 +1684,8 @@ gtk_sheet_moveto (GtkSheet *sheet, { 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 (g_sheet_row_get_visibility (sheet->row_geometry, min_row)) + adjust += g_sheet_row_get_height (sheet->row_geometry, min_row); if (adjust >= height) { @@ -2074,8 +1697,8 @@ gtk_sheet_moveto (GtkSheet *sheet, min_row ++; - y = ROW_TOP_YPIXEL (sheet, min_row) - sheet->voffset + - yyy_row_height (sheet, min_row) - 1; + y = g_sheet_row_start_pixel (sheet->row_geometry, min_row) + + g_sheet_row_get_height (sheet->row_geometry, min_row) - 1; } if (y < 0) @@ -2083,7 +1706,6 @@ gtk_sheet_moveto (GtkSheet *sheet, else sheet->vadjustment->value = y; - sheet->old_vadjustment = -1.; g_signal_emit_by_name (sheet->vadjustment, "value_changed"); @@ -2092,9 +1714,9 @@ gtk_sheet_moveto (GtkSheet *sheet, /* adjust horizontal scrollbar */ if (column >= 0 && col_align >= 0.0) { - x = COLUMN_LEFT_XPIXEL (sheet, column) - sheet->hoffset + x = COLUMN_LEFT_XPIXEL (sheet, column) - (gint) ( col_align*width + (1.0 - col_align)* - xxx_column_width (sheet, column)); + g_sheet_column_get_width (sheet->column_geometry, column)); /* This forces the sheet to scroll when you don't see the entire cell */ min_col = column; @@ -2103,8 +1725,8 @@ gtk_sheet_moveto (GtkSheet *sheet, { 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); + if (g_sheet_column_get_visibility (sheet->column_geometry, min_col)) + adjust += g_sheet_column_get_width (sheet->column_geometry, min_col); if (adjust >= width) { @@ -2113,8 +1735,8 @@ gtk_sheet_moveto (GtkSheet *sheet, min_col--; } min_col = MAX (min_col, 0); - x = COLUMN_LEFT_XPIXEL (sheet, min_col) - sheet->hoffset + - xxx_column_width (sheet, min_col) - 1; + x = COLUMN_LEFT_XPIXEL (sheet, min_col) + + g_sheet_column_get_width (sheet->column_geometry, min_col) - 1; } if (x < 0) @@ -2122,7 +1744,6 @@ gtk_sheet_moveto (GtkSheet *sheet, else sheet->hadjustment->value = x; - sheet->old_vadjustment = -1.; g_signal_emit_by_name (sheet->hadjustment, "value_changed"); } @@ -2168,13 +1789,12 @@ 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 >= g_sheet_row_get_row_count (sheet->row_geometry)) return; if (sheet->state != GTK_SHEET_NORMAL) @@ -2186,7 +1806,7 @@ gtk_sheet_select_row (GtkSheet * sheet, sheet->range.row0 = row; sheet->range.col0 = 0; sheet->range.rowi = row; - sheet->range.coli = xxx_column_count (sheet) - 1; + sheet->range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; sheet->active_cell.row = row; sheet->active_cell.col = 0; @@ -2201,7 +1821,7 @@ 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 >= g_sheet_column_get_column_count (sheet->column_geometry)) return; if (sheet->state != GTK_SHEET_NORMAL) @@ -2213,7 +1833,7 @@ gtk_sheet_select_column (GtkSheet * sheet, gint column) 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 = g_sheet_row_get_row_count (sheet->row_geometry) - 1; sheet->range.coli = column; sheet->active_cell.row = 0; sheet->active_cell.col = column; @@ -2231,16 +1851,16 @@ gtk_sheet_range_isvisible (const GtkSheet * sheet, { g_return_val_if_fail (sheet != NULL, FALSE); - if (range.row0 < 0 || range.row0 >= yyy_row_count (sheet)) + if (range.row0 < 0 || range.row0 >= g_sheet_row_get_row_count (sheet->row_geometry)) return FALSE; - if (range.rowi < 0 || range.rowi >= yyy_row_count (sheet)) + if (range.rowi < 0 || range.rowi >= g_sheet_row_get_row_count (sheet->row_geometry)) return FALSE; - if (range.col0 < 0 || range.col0 >= xxx_column_count (sheet)) + if (range.col0 < 0 || range.col0 >= g_sheet_column_get_column_count (sheet->column_geometry)) return FALSE; - if (range.coli < 0 || range.coli >= xxx_column_count (sheet)) + if (range.coli < 0 || range.coli >= g_sheet_column_get_column_count (sheet->column_geometry)) return FALSE; if (range.rowi < MIN_VISIBLE_ROW (sheet)) @@ -2285,126 +1905,35 @@ gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range) range->coli = MAX_VISIBLE_COLUMN (sheet); } -GtkAdjustment * -gtk_sheet_get_vadjustment (GtkSheet * sheet) + +static void +gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, + GtkAdjustment *hadjustment, + GtkAdjustment *vadjustment) { - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); + if ( sheet->vadjustment != vadjustment ) +{ + if (sheet->vadjustment) + g_object_unref (sheet->vadjustment); + sheet->vadjustment = vadjustment; + g_object_ref (vadjustment); - return sheet->vadjustment; -} + g_signal_connect (sheet->vadjustment, "value_changed", + G_CALLBACK (vadjustment_value_changed), + sheet); + } -GtkAdjustment * -gtk_sheet_get_hadjustment (GtkSheet * sheet) + if ( sheet->hadjustment != hadjustment ) { - g_return_val_if_fail (sheet != NULL, NULL); - g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); + if (sheet->hadjustment) + g_object_unref (sheet->hadjustment); + sheet->hadjustment = hadjustment; + g_object_ref (hadjustment); - return sheet->hadjustment; -} - -void -gtk_sheet_set_vadjustment (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->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) - { - g_object_ref (sheet->vadjustment); - g_object_ref_sink (sheet->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) - { - g_object_ref (sheet->hadjustment); - g_object_ref_sink (sheet->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); + g_signal_connect (sheet->hadjustment, "value_changed", + G_CALLBACK (hadjustment_value_changed), + sheet); + } } static void @@ -2425,7 +1954,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)); @@ -2469,16 +1997,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); } @@ -2512,8 +2030,6 @@ gtk_sheet_realize (GtkWidget * widget) gint attributes_mask; GdkGCValues values, auxvalues; GdkColormap *colormap; - GtkSheetChild *child; - GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); @@ -2537,6 +2053,8 @@ gtk_sheet_realize (GtkWidget * widget) 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 | @@ -2553,39 +2071,49 @@ gtk_sheet_realize (GtkWidget * widget) gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + 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); + 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.x = 0; attributes.y = 0; - attributes.width = sheet->sheet_window_width, + 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); @@ -2594,13 +2122,9 @@ gtk_sheet_realize (GtkWidget * widget) gdk_window_show (sheet->sheet_window); /* backing_pixmap */ - gtk_sheet_make_backing_pixmap (sheet, 0, 0); + gtk_sheet_make_backing_pixmap (sheet); /* 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); @@ -2611,13 +2135,15 @@ gtk_sheet_realize (GtkWidget * widget) 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 = 3; + 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); @@ -2627,7 +2153,6 @@ 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); if (sheet->column_titles_visible) @@ -2635,18 +2160,11 @@ gtk_sheet_realize (GtkWidget * widget) if (sheet->row_titles_visible) gdk_window_show (sheet->row_title_window); + sheet->hover_window = create_hover_window (); + size_allocate_row_title_buttons (sheet); size_allocate_column_title_buttons (sheet); - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - gtk_sheet_realize_child (sheet, child); - } - gtk_sheet_update_primary_selection (sheet); } @@ -2703,11 +2221,20 @@ gtk_sheet_unrealize (GtkWidget * widget) sheet = GTK_SHEET (widget); gdk_cursor_unref (sheet->cursor_drag); + sheet->cursor_drag = NULL; + + gdk_colormap_free_colors (gdk_colormap_get_system (), + &sheet->bg_color, 1); + + gdk_colormap_free_colors (gdk_colormap_get_system (), + &sheet->grid_color, 1); 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); @@ -2718,12 +2245,6 @@ gtk_sheet_unrealize (GtkWidget * widget) sheet->pixmap = NULL; } - sheet->column_title_window = NULL; - sheet->sheet_window = NULL; - sheet->xor_gc = NULL; - sheet->fg_gc = NULL; - sheet->bg_gc = NULL; - gtk_widget_unparent (sheet->entry_widget); if (sheet->button != NULL) gtk_widget_unparent (sheet->button); @@ -2736,8 +2257,6 @@ static void 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)); @@ -2784,38 +2303,17 @@ gtk_sheet_map (GtkWidget * widget) 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); - } - } - } } static void 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)); + GtkSheet *sheet = GTK_SHEET (widget); - sheet = GTK_SHEET (widget); + if (!GTK_WIDGET_MAPPED (widget)) + return; - if (GTK_WIDGET_MAPPED (widget)) - { GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); gdk_window_hide (sheet->sheet_window); @@ -2830,28 +2328,12 @@ gtk_sheet_unmap (GtkWidget * widget) if (GTK_WIDGET_MAPPED (sheet->button)) gtk_widget_unmap (sheet->button); - - children = sheet->children; - while (children) - { - child = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (child->widget) && - GTK_WIDGET_MAPPED (child->widget)) - { - gtk_widget_unmap (child->widget); - } - } - - } } static void gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) { - GtkWidget *widget; GdkGC *fg_gc, *bg_gc; GtkSheetCellAttr attributes; GdkRectangle area; @@ -2861,12 +2343,10 @@ gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) /* bail now if we arn't drawable yet */ 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; - - widget = GTK_WIDGET (sheet); + if (row < 0 || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; + if (col < 0 || col >= g_sheet_column_get_column_count (sheet->column_geometry)) return; + if (! g_sheet_column_get_visibility (sheet->column_geometry, col)) return; + if (! g_sheet_row_get_visibility (sheet->row_geometry, row)) return; gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -2877,18 +2357,14 @@ gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) 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); + area.x = g_sheet_column_start_pixel (sheet->column_geometry, col); + area.x -= sheet->hadjustment->value; + + area.y = g_sheet_row_start_pixel (sheet->row_geometry, row); + area.y -= sheet->vadjustment->value; - gdk_draw_rectangle (sheet->pixmap, - bg_gc, - TRUE, - area.x, - area.y, - area.width, - area.height); + area.width= g_sheet_column_get_width (sheet->column_geometry, col); + area.height = g_sheet_row_get_height (sheet->row_geometry, row); gdk_gc_set_line_attributes (sheet->fg_gc, 1, 0, 0, 0); @@ -2904,6 +2380,7 @@ gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) } } + static void gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) { @@ -2935,11 +2412,10 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) if (!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; - + if (row < 0 || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; + if (col < 0 || col >= g_sheet_column_get_column_count (sheet->column_geometry)) return; + if (! g_sheet_column_get_visibility (sheet->column_geometry, col)) return; + if (!g_sheet_row_get_visibility (sheet->row_geometry, row)) return; widget = GTK_WIDGET (sheet); @@ -2952,10 +2428,14 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) 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); + area.x = g_sheet_column_start_pixel (sheet->column_geometry, col); + area.x -= sheet->hadjustment->value; + + area.y = g_sheet_row_start_pixel (sheet->row_geometry, row); + area.y -= sheet->vadjustment->value; + + area.width = g_sheet_column_get_width (sheet->column_geometry, col); + area.height = g_sheet_row_get_height (sheet->row_geometry, row); layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), label); @@ -2983,7 +2463,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) y_pos = area.height - logical_rect.height; if (logical_rect.height > area.height) - y_pos = (logical_rect.height - area.height - 2 * CELLOFFSET) / 2; + y_pos = (logical_rect.height - area.height - 2 * COLUMN_TITLES_HEIGHT) / 2; else if (y_pos < 0) y_pos = 0; else if (y_pos + logical_rect.height > area.height) @@ -2991,7 +2471,7 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) text_width = rect.width; text_height = rect.height; - y = area.y + y_pos - CELLOFFSET; + y = area.y + y_pos - COLUMN_TITLES_HEIGHT; switch (attributes.justification) { @@ -3002,16 +2482,16 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) 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, + if (size >= text_width + COLUMN_TITLES_HEIGHT) break; + size += g_sheet_column_get_width (sheet->column_geometry, i); + g_sheet_column_set_right_text_column (sheet->column_geometry, i, MAX (col, - xxx_column_right_column (sheet, i))); + g_sheet_column_get_right_text_column (sheet->column_geometry, i))); } area.width = size; } area.x -= size; - xoffset += area.width - text_width - 2 * CELLOFFSET - + xoffset += area.width - text_width - 2 * COLUMN_TITLES_HEIGHT - attributes.border.width / 2; break; case GTK_JUSTIFY_CENTER: @@ -3023,25 +2503,25 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) { 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, + sizer += g_sheet_column_get_width (sheet->column_geometry, i); + g_sheet_column_set_left_text_column (sheet->column_geometry, i, MIN ( col, - xxx_column_left_column (sheet, i))); + g_sheet_column_get_left_text_column (sheet->column_geometry, 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, + sizel += g_sheet_column_get_width (sheet->column_geometry, i); + g_sheet_column_set_right_text_column (sheet->column_geometry, i, MAX (col, - xxx_column_right_column (sheet, i))); + g_sheet_column_get_right_text_column (sheet->column_geometry, i))); } size = MIN (sizel, sizer); } area.x -= sizel; - xoffset += sizel - text_width / 2 - CELLOFFSET; + xoffset += sizel - text_width / 2 - COLUMN_TITLES_HEIGHT; area.width = sizel + sizer; break; case GTK_JUSTIFY_LEFT: @@ -3051,12 +2531,12 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) 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, + if (size >= text_width + COLUMN_TITLES_HEIGHT) break; + size += g_sheet_column_get_width (sheet->column_geometry, i); + g_sheet_column_set_left_text_column (sheet->column_geometry, i, MIN ( col, - xxx_column_left_column (sheet, i))); + g_sheet_column_get_left_text_column (sheet->column_geometry, i))); } area.width = size; @@ -3069,23 +2549,13 @@ gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) gdk_draw_layout (sheet->pixmap, fg_gc, - area.x + xoffset + CELLOFFSET, - y, + area.x + xoffset + COLUMN_TITLES_HEIGHT, + area.y, layout); gdk_gc_set_clip_rectangle (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 @@ -3093,7 +2563,6 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) { gint i, j; GtkSheetRange drawing_range; - GdkRectangle area; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_SHEET (sheet)); @@ -3102,15 +2571,19 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; if (!GTK_WIDGET_MAPPED (GTK_WIDGET (sheet))) return; + if (sheet->sheet_window_width <= 0) return; + if (sheet->sheet_window_height <=0) return; + + if (sheet->pixmap == NULL) return ; + 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); + g_sheet_row_get_row_count (sheet->row_geometry) - 1); drawing_range.coli = MAX_VISIBLE_COLUMN (sheet); - gdk_draw_rectangle (sheet->pixmap, GTK_WIDGET (sheet)->style->white_gc, TRUE, @@ -3126,61 +2599,6 @@ gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range) drawing_range.coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet)); } - if (drawing_range.coli == xxx_column_count (sheet) - 1) - { - area.x = COLUMN_LEFT_XPIXEL (sheet, - xxx_column_count (sheet) - 1) + - xxx_column_width (sheet, xxx_column_count (sheet) - 1) + 1; - - area.y = 0; - - 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); - } - - if (drawing_range.rowi == yyy_row_count (sheet) - 1) - { - area.x = 0; - area.y = ROW_TOP_YPIXEL (sheet, - yyy_row_count (sheet) - 1) + - yyy_row_height (sheet, yyy_row_count (sheet) - 1) + 1; - - gdk_gc_set_foreground (sheet->fg_gc, &sheet->bg_color); - - 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); - } - for (i = drawing_range.row0; i <= drawing_range.rowi; i++) for (j = drawing_range.col0; j <= drawing_range.coli; j++) { @@ -3234,13 +2652,23 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) { if (gtk_sheet_cell_get_state (sheet, i, j) == GTK_STATE_SELECTED && - xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i)) + g_sheet_column_get_visibility (sheet->column_geometry, j) && g_sheet_row_get_visibility (sheet->row_geometry, i)) { - 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); + if ( sheet->row_titles_visible) + area.x += sheet->row_title_area.width; + + area.x -= sheet->hadjustment->value; + + area.y = g_sheet_row_start_pixel (sheet->row_geometry, i); + if ( sheet->column_titles_visible) + area.y += sheet->column_title_area.height; + + area.y -= sheet->vadjustment->value; + + + area.width= g_sheet_column_get_width (sheet->column_geometry, j); + area.height = g_sheet_row_get_height (sheet->row_geometry, i); if (i == sheet->range.row0) { @@ -3274,73 +2702,27 @@ gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range) static void gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, GtkSheetRange range) { - gint x, y, width, height; + gint 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); + if ( sheet->pixmap == NULL) return; - 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_drawable_get_size (sheet->pixmap, &width, &height); 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); + 0, 0, /* src */ + sheet->row_titles_visible ? sheet->row_title_area.width : 0, + sheet->column_titles_visible ? sheet->column_title_area.height : 0, + width, height); } +static void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, + GtkJustification justification, + const gchar *text); -void -gtk_sheet_set_cell_text (GtkSheet *sheet, gint row, gint col, const gchar *text) -{ - 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) @@ -3351,7 +2733,7 @@ safe_strcmp (const gchar *s1, const gchar *s2) return strcmp (s1, s2); } -void +static void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, GtkJustification justification, const gchar *text) @@ -3366,7 +2748,7 @@ gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, 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 >= g_sheet_column_get_column_count (sheet->column_geometry) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; if (col < 0 || row < 0) return; gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -3403,15 +2785,14 @@ gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, range.coli = MAX_VISIBLE_COLUMN (sheet); if (gtk_sheet_autoresize (sheet) && - text_width > xxx_column_width (sheet, col) - - 2 * CELLOFFSET- attributes.border.width) + text_width > g_sheet_column_get_width (sheet->column_geometry, col) - + 2 * COLUMN_TITLES_HEIGHT- attributes.border.width) { - gtk_sheet_set_column_width (sheet, col, text_width + 2 * CELLOFFSET + gtk_sheet_set_column_width (sheet, col, text_width + 2 * COLUMN_TITLES_HEIGHT + 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); } @@ -3428,8 +2809,8 @@ 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 >= g_sheet_column_get_column_count (sheet->column_geometry) || + row >= g_sheet_row_get_row_count (sheet->row_geometry)) return; if (column < 0 || row < 0) return; @@ -3440,11 +2821,8 @@ gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint column) gtk_sheet_real_cell_clear (sheet, row, column); - if (!GTK_SHEET_IS_FROZEN (sheet)) - { gtk_sheet_range_draw (sheet, &range); } -} static void gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column) @@ -3479,17 +2857,17 @@ gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range) if (!range) { clear.row0 = 0; - clear.rowi = yyy_row_count (sheet) - 1; + clear.rowi = g_sheet_row_get_row_count (sheet->row_geometry) - 1; clear.col0 = 0; - clear.coli = xxx_column_count (sheet) - 1; + clear.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 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 ); + clear.rowi = MIN (clear.rowi, g_sheet_row_get_row_count (sheet->row_geometry) - 1 ); + clear.coli = MIN (clear.coli, g_sheet_column_get_column_count (sheet->column_geometry) - 1 ); for (i = clear.row0; i <= clear.rowi; i++) for (j = clear.col0; j <= clear.coli; j++) @@ -3521,7 +2899,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 >= g_sheet_column_get_column_count (sheet->column_geometry) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return NULL; if (col < 0 || row < 0) return NULL; @@ -3542,7 +2920,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 >= g_sheet_column_get_column_count (sheet->column_geometry) || row >= g_sheet_row_get_row_count (sheet->row_geometry)) return 0; if (col < 0 || row < 0) return 0; state = sheet->state; @@ -3570,11 +2948,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, @@ -3596,28 +2973,27 @@ 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; - else - { - trow = ROW_FROM_YPIXEL (sheet, y); - if (trow > yyy_row_count (sheet)) + y += sheet->vadjustment->value; + + trow = yyy_row_ypixel_to_row (sheet, y); + if (trow > g_sheet_row_get_row_count (sheet->row_geometry)) return FALSE; *row = trow; - } - if ( x < sheet->row_title_area.width + sheet->row_title_area.x) - *column = -1; - else - { + if ( sheet->row_titles_visible) + x -= sheet->row_title_area.width; + + x += sheet->hadjustment->value; + tcol = COLUMN_FROM_XPIXEL (sheet, x); - if (tcol > xxx_column_count (sheet)) + if (tcol > g_sheet_column_get_column_count (sheet->column_geometry)) return FALSE; *column = tcol; - } return TRUE; } @@ -3631,22 +3007,17 @@ 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 >= g_sheet_row_get_row_count (sheet->row_geometry) || column >= g_sheet_column_get_column_count (sheet->column_geometry)) 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 : COLUMN_LEFT_XPIXEL (sheet, column); + area->y = (row == -1) ? 0 : g_sheet_row_start_pixel (sheet->row_geometry, row); + area->width= (column == -1) ? sheet->row_title_area.width - : xxx_column_width (sheet, column); + : g_sheet_column_get_width (sheet->column_geometry, column); area->height= (row == -1) ? sheet->column_title_area.height - : yyy_row_height (sheet, row); + : g_sheet_row_get_height (sheet->row_geometry, row); return TRUE; } @@ -3658,7 +3029,7 @@ gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column) g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); if (row < - 1 || column < - 1) return FALSE; - if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet)) + if (row >= g_sheet_row_get_row_count (sheet->row_geometry) || column >= g_sheet_column_get_column_count (sheet->column_geometry)) return FALSE; if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) @@ -3718,8 +3089,6 @@ gtk_sheet_entry_changed (GtkWidget *widget, gpointer data) text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); - GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IS_FROZEN); - if (text && strlen (text) > 0) { gtk_sheet_get_attributes (sheet, row, col, &attributes); @@ -3727,9 +3096,6 @@ 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; } @@ -3782,9 +3148,6 @@ gtk_sheet_hide_active_cell (GtkSheet *sheet) 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); @@ -3796,21 +3159,9 @@ gtk_sheet_hide_active_cell (GtkSheet *sheet) 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 @@ -3823,7 +3174,7 @@ gtk_sheet_activate_cell (GtkSheet *sheet, gint row, gint col) if (row < 0 || col < 0) return FALSE; - if ( row > yyy_row_count (sheet) || col > xxx_column_count (sheet)) + if ( row > g_sheet_row_get_row_count (sheet->row_geometry) || col > g_sheet_column_get_column_count (sheet->column_geometry)) return FALSE; if (!veto) return FALSE; @@ -3844,6 +3195,8 @@ 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); g_signal_connect (gtk_sheet_get_entry (sheet), @@ -3941,18 +3294,21 @@ gtk_sheet_draw_active_cell (GtkSheet *sheet) } + static void -gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height) +gtk_sheet_make_backing_pixmap (GtkSheet *sheet) { gint pixmap_width, pixmap_height; + gint width, 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; - } + width = sheet->sheet_window_width ; + height = sheet->sheet_window_height ; + + + if ( width <= 0) return; + if ( height <= 0) return; if (!sheet->pixmap) { @@ -3960,7 +3316,8 @@ gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height) sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, width, height, - 1); - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); + + gtk_sheet_range_draw (sheet, NULL); } else { @@ -3973,7 +3330,7 @@ gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height) sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, width, height, - 1); - if (!GTK_SHEET_IS_FROZEN (sheet)) gtk_sheet_range_draw (sheet, NULL); + gtk_sheet_range_draw (sheet, NULL); } } } @@ -4017,7 +3374,7 @@ 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) && + g_sheet_column_get_visibility (sheet->column_geometry, j) && g_sheet_row_get_visibility (sheet->row_geometry, 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,10 +3394,10 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) if (mask1 != mask2) { x = COLUMN_LEFT_XPIXEL (sheet, j); - y = ROW_TOP_YPIXEL (sheet, i); + y = g_sheet_row_start_pixel (sheet->row_geometry, 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); + g_sheet_column_get_width (sheet->column_geometry, j); + height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == sheet->range.row0) { @@ -4055,24 +3412,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); + y = g_sheet_row_start_pixel (sheet->row_geometry, i); width = COLUMN_LEFT_XPIXEL (sheet, j)- x+ - xxx_column_width (sheet, j); + g_sheet_column_get_width (sheet->column_geometry, j); - height = ROW_TOP_YPIXEL (sheet, i)- y + yyy_row_height (sheet, i); + height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == new_range.row0) { @@ -4108,13 +3455,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)) + g_sheet_column_get_visibility (sheet->column_geometry, j) && g_sheet_row_get_visibility (sheet->row_geometry, i)) { 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); + y = g_sheet_row_start_pixel (sheet->row_geometry, i); + width = COLUMN_LEFT_XPIXEL (sheet, j) - x + g_sheet_column_get_width (sheet->column_geometry, j); + height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == sheet->range.row0) { @@ -4129,15 +3476,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); } } } @@ -4152,14 +3490,14 @@ 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) && + g_sheet_column_get_visibility (sheet->column_geometry, j) && g_sheet_row_get_visibility (sheet->row_geometry, 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); + y = g_sheet_row_start_pixel (sheet->row_geometry, i); + width = COLUMN_LEFT_XPIXEL (sheet, j) - x + g_sheet_column_get_width (sheet->column_geometry, j); + height = g_sheet_row_start_pixel (sheet->row_geometry, i) - y + g_sheet_row_get_height (sheet->row_geometry, i); if (i == new_range.row0) { @@ -4190,7 +3528,7 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) for (j = aux_range.col0; j <= aux_range.coli; j++) { - if (xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i)) + if (g_sheet_column_get_visibility (sheet->column_geometry, j) && g_sheet_row_get_visibility (sheet->row_geometry, i)) { state = gtk_sheet_cell_get_state (sheet, i, j); @@ -4207,9 +3545,9 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) 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); + y = g_sheet_row_start_pixel (sheet->row_geometry, i); + width = g_sheet_column_get_width (sheet->column_geometry, j); + height = g_sheet_row_get_height (sheet->row_geometry, i); if (mask2 & 1) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, @@ -4251,177 +3589,69 @@ gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range) *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; + gint width, height; - widget = GTK_WIDGET (sheet); + gint x = COLUMN_LEFT_XPIXEL (sheet, new_range.col0); + gint y = g_sheet_row_start_pixel (sheet->row_geometry, new_range.row0); + + if ( sheet->row_titles_visible) + x += sheet->row_title_area.width; + + x -= sheet->hadjustment->value; + + if ( sheet->column_titles_visible) + y += sheet->column_title_area.height; + + y -= sheet->vadjustment->value; - 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); + width = COLUMN_LEFT_XPIXEL (sheet, new_range.coli) - + COLUMN_LEFT_XPIXEL (sheet, new_range.col0) + + + g_sheet_column_get_width (sheet->column_geometry, new_range.coli); - height = ROW_TOP_YPIXEL (sheet, new_range.rowi) - y + - yyy_row_height (sheet, new_range.rowi); + height = g_sheet_row_start_pixel (sheet->row_geometry, new_range.rowi) - + g_sheet_row_start_pixel (sheet->row_geometry, new_range.row0) + + + g_sheet_row_get_height (sheet->row_geometry, new_range.rowi); area.x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet)); - area.y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet)); + if ( sheet->row_titles_visible) + area.x += sheet->row_title_area.width; + + area.x -= sheet->hadjustment->value; + + area.y = g_sheet_row_start_pixel (sheet->row_geometry, MIN_VISIBLE_ROW (sheet)); + if ( sheet->column_titles_visible) + area.y += sheet->column_title_area.height; + + area.y -= sheet->vadjustment->value; + + 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_draw_rectangle (sheet->sheet_window, + sheet->xor_gc, + FALSE, + x, y, + width - 2, + height - 2); gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL); - - - gtk_sheet_draw_corners (sheet, new_range); } + static void -gtk_sheet_draw_corners (GtkSheet *sheet, GtkSheetRange range) -{ - gint x, y; - guint width = 1; - - if (gtk_sheet_cell_isvisible (sheet, range.row0, range.col0)) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - y = ROW_TOP_YPIXEL (sheet, range.row0); - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - 1, - y - 1, - x - 1, - y - 1, - 3, - 3); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - 1, y - 1, - 3, 3); - } - - if (gtk_sheet_cell_isvisible (sheet, range.row0, range.coli) || - sheet->state == GTK_SHEET_COLUMN_SELECTED) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+ - xxx_column_width (sheet, range.coli); - y = ROW_TOP_YPIXEL (sheet, range.row0); - width = 1; - if (sheet->state == GTK_SHEET_COLUMN_SELECTED) - { - y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet))+3; - width = 3; - } - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); - } - - if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.col0) || - sheet->state == GTK_SHEET_ROW_SELECTED) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - y = ROW_TOP_YPIXEL (sheet, range.rowi)+ - yyy_row_height (sheet, range.rowi); - width = 1; - if (sheet->state == GTK_SHEET_ROW_SELECTED) - { - x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet))+3; - width = 3; - } - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); - } - - if (gtk_sheet_cell_isvisible (sheet, range.rowi, range.coli)) - { - x = COLUMN_LEFT_XPIXEL (sheet, range.coli)+ - xxx_column_width (sheet, range.coli); - y = ROW_TOP_YPIXEL (sheet, range.rowi)+ - yyy_row_height (sheet, range.rowi); - width = 1; - if (sheet->state == GTK_SHEET_RANGE_SELECTED) width = 3; - if (sheet->state == GTK_SHEET_NORMAL) width = 3; - gdk_draw_drawable (sheet->sheet_window, - GTK_WIDGET (sheet)->style->fg_gc[GTK_STATE_NORMAL], - sheet->pixmap, - x - width, - y - width, - x - width, - y - width, - 2 * width + 1, - 2 * width + 1); - gdk_draw_rectangle (sheet->sheet_window, - sheet->xor_gc, - TRUE, - x - width + width / 2, y - width + width / 2, - 2 + width, 2 + width); - - } - -} - - -static void -gtk_sheet_real_select_range (GtkSheet * sheet, - const GtkSheetRange * range) +gtk_sheet_real_select_range (GtkSheet * sheet, + const GtkSheetRange * range) { gint state; @@ -4454,8 +3684,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; @@ -4489,7 +3718,6 @@ gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range) sheet->state = GTK_SHEET_RANGE_SELECTED; gtk_sheet_real_select_range (sheet, NULL); - } void @@ -4529,8 +3757,6 @@ gtk_sheet_real_unselect_range (GtkSheet * sheet, sheet->range.rowi = -1; sheet->range.col0 = -1; sheet->range.coli = -1; - - gtk_sheet_position_children (sheet); } @@ -4545,15 +3771,23 @@ gtk_sheet_expose (GtkWidget * widget, g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); + g_print ("%s %p\n", __FUNCTION__, widget); sheet = GTK_SHEET (widget); if (GTK_WIDGET_DRAWABLE (widget)) { - range.row0 = ROW_FROM_YPIXEL (sheet, event->area.y); + range.row0 = yyy_row_ypixel_to_row (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); + range.rowi = yyy_row_ypixel_to_row (sheet, + event->area.y + event->area.height); + + range.coli = COLUMN_FROM_XPIXEL (sheet, + event->area.x + event->area.width); + + g_print ("Redrawing rows %d--%d, columns %d--%d\n", + range.row0, range.rowi, range.col0, range.coli); + /* exposure events on the sheet */ if (event->window == sheet->row_title_window && @@ -4568,7 +3802,9 @@ gtk_sheet_expose (GtkWidget * widget, sheet->column_titles_visible) { gint i; - for (i = MIN_VISIBLE_COLUMN (sheet); i <= MAX_VISIBLE_COLUMN (sheet); i++) + for (i = MIN_VISIBLE_COLUMN (sheet); + i <= MAX_VISIBLE_COLUMN (sheet); + ++i) gtk_sheet_column_title_button_draw (sheet, i); } @@ -4664,8 +3900,15 @@ 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) @@ -4794,9 +4037,14 @@ gtk_sheet_button_press (GtkWidget * widget, if (event->window == sheet->column_title_window) { gtk_widget_get_pointer (widget, &x, &y); + if ( sheet->row_titles_visible) + x -= sheet->row_title_area.width; + + x += sheet->hadjustment->value; + column = COLUMN_FROM_XPIXEL (sheet, x); - if (xxx_column_is_sensitive (sheet, column)) + if (g_sheet_column_get_sensitivity (sheet->column_geometry, column)) { gtk_sheet_click_cell (sheet, - 1, column, &veto); gtk_grab_add (GTK_WIDGET (sheet)); @@ -4808,8 +4056,13 @@ 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 = yyy_row_ypixel_to_row (sheet, y); + if (g_sheet_row_get_sensitivity (sheet->row_geometry, row)) { gtk_sheet_click_cell (sheet, row, - 1, &veto); gtk_grab_add (GTK_WIDGET (sheet)); @@ -4826,18 +4079,21 @@ gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto) { *veto = TRUE; - if (row >= yyy_row_count (sheet) || column >= xxx_column_count (sheet)) + if (row >= g_sheet_row_get_row_count (sheet->row_geometry) || column >= g_sheet_column_get_column_count (sheet->column_geometry)) { *veto = FALSE; return; } if (column >= 0 && row >= 0) - if (! xxx_column_is_visible (sheet, column) || !yyy_row_is_visible (sheet, row)) + { + if (! g_sheet_column_get_visibility (sheet->column_geometry, column) + || !g_sheet_row_get_visibility (sheet->row_geometry, row)) { *veto = FALSE; return; } + } _gtkextra_signal_emit (GTK_OBJECT (sheet), sheet_signals[TRAVERSE], sheet->active_cell.row, sheet->active_cell.col, @@ -4873,8 +4129,8 @@ gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto) { 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 = g_sheet_row_get_row_count (sheet->row_geometry) - 1; + sheet->range.coli = g_sheet_column_get_column_count (sheet->column_geometry) - 1; sheet->active_cell.row = 0; sheet->active_cell.col = 0; gtk_sheet_select_range (sheet, NULL); @@ -4919,24 +4175,24 @@ static gint gtk_sheet_button_release (GtkWidget * widget, GdkEventButton * event) { - GtkSheet *sheet; - gint x, y; + gint y; - 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); 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; } @@ -4948,8 +4204,8 @@ gtk_sheet_button_release (GtkWidget * widget, gdk_pointer_ungrab (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; } @@ -5028,6 +4284,9 @@ gtk_sheet_button_release (GtkWidget * widget, return TRUE; } + + + /* Shamelessly lifted from gtktooltips */ static gboolean gtk_sheet_subtitle_paint_window (GtkWidget *tip_window) @@ -5043,10 +4302,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); @@ -5095,16 +4361,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); @@ -5150,28 +4406,25 @@ 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; 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); - show_subtitle (sheet, row, column, text ); + show_subtitle (sheet, -1, column, text ); g_free (text); } @@ -5180,9 +4433,8 @@ 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; @@ -5200,11 +4452,12 @@ gtk_sheet_motion (GtkWidget * widget, 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 { @@ -5224,9 +4477,8 @@ 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) @@ -5254,7 +4506,6 @@ 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 (!GTK_SHEET_IN_SELECTION (sheet) && POSSIBLE_YDRAG (sheet, y, &column)) { new_cursor = GDK_SB_V_DOUBLE_ARROW; @@ -5293,8 +4544,10 @@ gtk_sheet_motion (GtkWidget * widget, 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); @@ -5321,18 +4574,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; 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,14 +4609,14 @@ gtk_sheet_motion (GtkWidget * widget, { GtkSheetRange aux; column = COLUMN_FROM_XPIXEL (sheet, x)- sheet->drag_cell.col; - row = ROW_FROM_YPIXEL (sheet, y)- sheet->drag_cell.row; + row = yyy_row_ypixel_to_row (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 < g_sheet_row_get_row_count (sheet->row_geometry) && + aux.col0 + column >= 0 && aux.coli + column < g_sheet_column_get_column_count (sheet->column_geometry)) { aux = sheet->drag_range; sheet->drag_range.row0 = sheet->range.row0 + row; @@ -5386,19 +4638,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 - COLUMN_LEFT_XPIXEL (sheet, sheet->drag_cell.col)) > - abs (y - ROW_TOP_YPIXEL (sheet, sheet->drag_cell.row))) v_h = 2; + abs (y - g_sheet_row_start_pixel (sheet->row_geometry, sheet->drag_cell.row))) v_h = 2; current_col = COLUMN_FROM_XPIXEL (sheet, x); - current_row = ROW_FROM_YPIXEL (sheet, y); + current_row = yyy_row_ypixel_to_row (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; + g_sheet_column_get_width (sheet->column_geometry, current_col) / 2; if (column > 0) { if (x < col_threshold) @@ -5409,8 +4660,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 = g_sheet_row_start_pixel (sheet->row_geometry, current_row) + + g_sheet_row_get_height (sheet->row_geometry, current_row)/2; if (row > 0) { if (y < row_threshold) @@ -5433,8 +4684,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 < g_sheet_row_get_row_count (sheet->row_geometry) && + aux.col0 + column >= 0 && aux.coli + column < g_sheet_column_get_column_count (sheet->column_geometry)) { aux = sheet->drag_range; sheet->drag_range = sheet->range; @@ -5467,19 +4718,32 @@ gtk_sheet_motion (GtkWidget * widget, return TRUE; } +static gboolean +gtk_sheet_crossing_notify (GtkWidget *widget, + GdkEventCrossing *event) +{ + GtkSheet *sheet = GTK_SHEET (widget); + + if (event->window == sheet->column_title_window) + sheet->column_title_under = event->type == GDK_ENTER_NOTIFY; + else if (event->window == sheet->row_title_window) + sheet->row_title_under = event->type == GDK_ENTER_NOTIFY; + + return TRUE; +} + + static gboolean gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column) { - 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.; + gint row_move = FALSE; + gint column_move = FALSE; + gfloat row_align = -1.0; + gfloat col_align = -1.0; height = sheet->sheet_window_height; width = sheet->sheet_window_width; @@ -5487,11 +4751,11 @@ gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column) 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); + new_row = MIN (g_sheet_row_get_row_count (sheet->row_geometry) - 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) + if (MAX_VISIBLE_ROW (sheet) == g_sheet_row_get_row_count (sheet->row_geometry) - 1 && + g_sheet_row_start_pixel (sheet->row_geometry, g_sheet_row_get_row_count (sheet->row_geometry) - 1) + + g_sheet_row_get_height (sheet->row_geometry, g_sheet_row_get_row_count (sheet->row_geometry) - 1) < height) { row_move = FALSE; row_align = -1.; @@ -5505,11 +4769,11 @@ gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column) 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); + new_col = MIN (g_sheet_column_get_column_count (sheet->column_geometry) - 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) + if (MAX_VISIBLE_COLUMN (sheet) == (g_sheet_column_get_column_count (sheet->column_geometry) - 1) && + COLUMN_LEFT_XPIXEL (sheet, g_sheet_column_get_column_count (sheet->column_geometry) - 1) + + g_sheet_column_get_width (sheet->column_geometry, g_sheet_column_get_column_count (sheet->column_geometry) - 1) < width) { column_move = FALSE; col_align = -1.; @@ -5517,7 +4781,7 @@ gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column) } if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED) { - col_align = 0.; + col_align = 0.0; column_move = TRUE; } @@ -5551,10 +4815,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 = g_sheet_column_get_column_count (sheet->column_geometry) - 1; break; case GTK_SHEET_COLUMN_SELECTED: - row = yyy_row_count (sheet) - 1; + row = g_sheet_row_get_row_count (sheet->row_geometry) - 1; break; case GTK_SHEET_NORMAL: sheet->state = GTK_SHEET_RANGE_SELECTED; @@ -5564,15 +4828,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; @@ -5640,10 +4895,10 @@ gtk_sheet_key_press (GtkWidget *widget, 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) + if (row < g_sheet_row_get_row_count (sheet->row_geometry) - 1) { row = row + scroll; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet)- 1) + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row < g_sheet_row_get_row_count (sheet->row_geometry) - 1) row++; } gtk_sheet_click_cell (sheet, row, col, &veto); @@ -5659,7 +4914,7 @@ gtk_sheet_key_press (GtkWidget *widget, if (col > 0) { col = col - scroll; - while (! xxx_column_is_visible (sheet, col) && col > 0) col--; + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && col > 0) col--; col = MAX (0, col); } gtk_sheet_click_cell (sheet, row, col, &veto); @@ -5672,11 +4927,11 @@ gtk_sheet_key_press (GtkWidget *widget, 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) + if (col < g_sheet_column_get_column_count (sheet->column_geometry) - 1) { col = col + scroll; - while (! xxx_column_is_visible (sheet, col) && - col < xxx_column_count (sheet) - 1) + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && + col < g_sheet_column_get_column_count (sheet->column_geometry) - 1) col++; } gtk_sheet_click_cell (sheet, row, col, &veto); @@ -5697,7 +4952,7 @@ gtk_sheet_key_press (GtkWidget *widget, if (sheet->selection_cell.row > 0) { row = sheet->selection_cell.row - scroll; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row > 0) row--; row = MAX (0, row); gtk_sheet_extend_selection (sheet, row, sheet->selection_cell.col); } @@ -5710,7 +4965,7 @@ gtk_sheet_key_press (GtkWidget *widget, if (state == GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN (sheet); row = row - scroll; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row > 0) row--; row = MAX (0, row); gtk_sheet_click_cell (sheet, row, col, &veto); extend_selection = FALSE; @@ -5727,26 +4982,26 @@ gtk_sheet_key_press (GtkWidget *widget, gtk_sheet_click_cell (sheet, row, col, &veto); if (!veto) break; } - if (sheet->selection_cell.row < yyy_row_count (sheet)- 1) + if (sheet->selection_cell.row < g_sheet_row_get_row_count (sheet->row_geometry) - 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); + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row < g_sheet_row_get_row_count (sheet->row_geometry) - 1) row++; + row = MIN (g_sheet_row_get_row_count (sheet->row_geometry) - 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 (sheet->active_cell.row < g_sheet_row_get_row_count (sheet->row_geometry) - 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); + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row < g_sheet_row_get_row_count (sheet->row_geometry) - 1) row++; + row = MIN (g_sheet_row_get_row_count (sheet->row_geometry) - 1, row); } gtk_sheet_click_cell (sheet, row, col, &veto); extend_selection = FALSE; @@ -5761,10 +5016,10 @@ gtk_sheet_key_press (GtkWidget *widget, gtk_sheet_click_cell (sheet, row, col, &veto); if (!veto) break; } - if (sheet->selection_cell.col < xxx_column_count (sheet) - 1) + if (sheet->selection_cell.col < g_sheet_column_get_column_count (sheet->column_geometry) - 1) { col = sheet->selection_cell.col + 1; - while (! xxx_column_is_visible (sheet, col) && col < xxx_column_count (sheet) - 1) + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && col < g_sheet_column_get_column_count (sheet->column_geometry) - 1) col++; gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col); } @@ -5772,14 +5027,14 @@ gtk_sheet_key_press (GtkWidget *widget, } col = sheet->active_cell.col; row = sheet->active_cell.row; - if (sheet->active_cell.col < xxx_column_count (sheet) - 1) + if (sheet->active_cell.col < g_sheet_column_get_column_count (sheet->column_geometry) - 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++; + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && col < g_sheet_column_get_column_count (sheet->column_geometry) - 1) col++; if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0 || force_move) { @@ -5803,7 +5058,7 @@ gtk_sheet_key_press (GtkWidget *widget, if (sheet->selection_cell.col > 0) { col = sheet->selection_cell.col - 1; - while (! xxx_column_is_visible (sheet, col) && col > 0) col--; + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && col > 0) col--; gtk_sheet_extend_selection (sheet, sheet->selection_cell.row, col); } return TRUE; @@ -5814,7 +5069,7 @@ gtk_sheet_key_press (GtkWidget *widget, 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--; + while (! g_sheet_column_get_visibility (sheet->column_geometry, col) && col > 0) col--; col = MAX (0, col); if (strlen (gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)))) == 0 @@ -5828,13 +5083,13 @@ gtk_sheet_key_press (GtkWidget *widget, break; case GDK_Home: row = 0; - while (!yyy_row_is_visible (sheet, row) && row < yyy_row_count (sheet) - 1) row++; + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row < g_sheet_row_get_row_count (sheet->row_geometry) - 1) row++; gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto); extend_selection = FALSE; break; case GDK_End: - row = yyy_row_count (sheet) - 1; - while (!yyy_row_is_visible (sheet, row) && row > 0) row--; + row = g_sheet_row_get_row_count (sheet->row_geometry) - 1; + while (!g_sheet_row_get_visibility (sheet->row_geometry, row) && row > 0) row--; gtk_sheet_click_cell (sheet, row, sheet->active_cell.col, &veto); extend_selection = FALSE; break; @@ -5864,9 +5119,6 @@ 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)); @@ -5884,15 +5136,6 @@ 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); - } } @@ -5945,10 +5188,16 @@ 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; + 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->sheet_window_width -= sheet->row_title_area.width; + } + + sheet->column_title_area.width = sheet_allocation.width ; + + if (GTK_WIDGET_REALIZED (widget) && sheet->column_titles_visible) gdk_window_move_resize (sheet->column_title_window, sheet->column_title_area.x, @@ -5956,8 +5205,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); @@ -5966,7 +5213,11 @@ gtk_sheet_size_allocate (GtkWidget * widget, 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->sheet_window_height -= sheet->column_title_area.height; + } + sheet->row_title_area.height = sheet_allocation.height - sheet->row_title_area.y; @@ -5983,8 +5234,7 @@ gtk_sheet_size_allocate (GtkWidget * widget, size_allocate_column_title_buttons (sheet); /* re - scale backing pixmap */ - gtk_sheet_make_backing_pixmap (sheet, 0, 0); - gtk_sheet_position_children (sheet); + gtk_sheet_make_backing_pixmap (sheet); /* set the scrollbars adjustments */ adjust_scrollbars (sheet); @@ -6000,12 +5250,12 @@ size_allocate_column_title_buttons (GtkSheet * sheet) if (!GTK_WIDGET_REALIZED (sheet)) return; + width = sheet->sheet_window_width; x = 0; if (sheet->row_titles_visible) { - width -= sheet->row_title_area.width; x = sheet->row_title_area.width; } @@ -6020,8 +5270,7 @@ 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) == g_sheet_column_get_column_count (sheet->column_geometry) - 1) gdk_window_clear_area (sheet->column_title_window, 0, 0, sheet->column_title_area.width, @@ -6050,7 +5299,6 @@ size_allocate_row_title_buttons (GtkSheet * sheet) if (sheet->column_titles_visible) { - height -= sheet->column_title_area.height; y = sheet->column_title_area.height; } @@ -6064,7 +5312,7 @@ 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) == g_sheet_row_get_row_count (sheet->row_geometry) - 1) gdk_window_clear_area (sheet->row_title_window, 0, 0, sheet->row_title_area.width, @@ -6076,7 +5324,7 @@ size_allocate_row_title_buttons (GtkSheet * sheet) for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++) { - if ( i >= yyy_row_count (sheet)) + if ( i >= g_sheet_row_get_row_count (sheet->row_geometry)) break; gtk_sheet_row_title_button_draw (sheet, i); } @@ -6151,23 +5399,33 @@ gtk_sheet_size_allocate_entry (GtkSheet *sheet) 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); + column_width = g_sheet_column_get_width (sheet->column_geometry, sheet->active_cell.col); size = MIN (text_size, max_size); - size = MAX (size, column_width - 2 * CELLOFFSET); + size = MAX (size, column_width - 2 * COLUMN_TITLES_HEIGHT); 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.y = g_sheet_row_start_pixel (sheet->row_geometry, sheet->active_cell.row); + if ( sheet->column_titles_visible) + shentry_allocation.y += sheet->column_title_area.height; + + shentry_allocation.y -= sheet->vadjustment->value; + + if ( sheet->row_titles_visible) + shentry_allocation.x += sheet->row_title_area.width; + + shentry_allocation.x -= sheet->hadjustment->value; + shentry_allocation.width = column_width; - shentry_allocation.height = yyy_row_height (sheet, sheet->active_cell.row); + shentry_allocation.height = g_sheet_row_get_height (sheet->row_geometry, sheet->active_cell.row); if (GTK_IS_ITEM_ENTRY (sheet->entry_widget)) { - shentry_allocation.height -= 2 * CELLOFFSET; - shentry_allocation.y += CELLOFFSET; + shentry_allocation.height -= 2 * COLUMN_TITLES_HEIGHT; + shentry_allocation.y += COLUMN_TITLES_HEIGHT; shentry_allocation.width = size; switch (GTK_ITEM_ENTRY (sheet_entry)->justification) @@ -6176,11 +5434,11 @@ gtk_sheet_size_allocate_entry (GtkSheet *sheet) shentry_allocation.x += column_width / 2 - size / 2; break; case GTK_JUSTIFY_RIGHT: - shentry_allocation.x += column_width - size - CELLOFFSET; + shentry_allocation.x += column_width - size - COLUMN_TITLES_HEIGHT; break; case GTK_JUSTIFY_LEFT: case GTK_JUSTIFY_FILL: - shentry_allocation.x += CELLOFFSET; + shentry_allocation.x += COLUMN_TITLES_HEIGHT; break; } } @@ -6227,7 +5485,7 @@ gtk_sheet_entry_set_max_size (GtkSheet *sheet) g_free (s); break; } - size +=xxx_column_width (sheet, i); + size +=g_sheet_column_get_width (sheet->column_geometry, i); } size = MIN (size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL (sheet, col)); break; @@ -6239,13 +5497,13 @@ gtk_sheet_entry_set_max_size (GtkSheet *sheet) g_free (s); break; } - size +=xxx_column_width (sheet, i); + size +=g_sheet_column_get_width (sheet->column_geometry, i); } break; case GTK_JUSTIFY_CENTER: for (i = col + 1; i <= MAX_VISIBLE_COLUMN (sheet); i++) { - sizer += xxx_column_width (sheet, i); + sizer += g_sheet_column_get_width (sheet->column_geometry, i); } for (i = col - 1; i >= MIN_VISIBLE_COLUMN (sheet); i--) { @@ -6254,14 +5512,14 @@ gtk_sheet_entry_set_max_size (GtkSheet *sheet) g_free (s); break; } - sizel +=xxx_column_width (sheet, i); + sizel +=g_sheet_column_get_width (sheet->column_geometry, i); } size = 2 * MIN (sizel, sizer); break; } if (size != 0) - size += xxx_column_width (sheet, col); + size += g_sheet_column_get_width (sheet->column_geometry, col); GTK_ITEM_ENTRY (sheet->entry_widget)->text_max_size = size; } @@ -6331,9 +5589,6 @@ gtk_sheet_get_entry (GtkSheet *sheet) { GtkWidget *parent; GtkWidget *entry = NULL; - GtkTableChild *table_child; - GtkBoxChild *box_child; - GList *children = NULL; g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); @@ -6344,9 +5599,6 @@ gtk_sheet_get_entry (GtkSheet *sheet) 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)) { gtk_container_forall (GTK_CONTAINER (parent), find_entry, &entry); @@ -6355,27 +5607,6 @@ gtk_sheet_get_entry (GtkSheet *sheet) return entry; } - if (!children) return NULL; - - while (children) - { - if (GTK_IS_TABLE (parent)) - { - table_child = children->data; - entry = table_child->widget; - } - if (GTK_IS_BOX (parent)) - { - box_child = children->data; - entry = box_child->widget; - } - - if (GTK_IS_ENTRY (entry)) - break; - children = children->next; - } - - if (!GTK_IS_ENTRY (entry)) return NULL; return (entry); @@ -6400,7 +5631,6 @@ gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, { GtkShadowType shadow_type; gint text_width = 0, text_height = 0; - GtkSheetChild *child = NULL; PangoAlignment align = PANGO_ALIGN_LEFT; gboolean rtl ; @@ -6412,6 +5642,7 @@ gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, 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,11 +5675,13 @@ 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 (GTK_WIDGET (sheet)) - + 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; @@ -6480,11 +5713,11 @@ gtk_sheet_button_draw (GtkSheet *sheet, GdkWindow *window, switch (button->justification) { case GTK_JUSTIFY_LEFT: - real_x = allocation.x + CELLOFFSET; + 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 - CELLOFFSET; + real_x = allocation.x + allocation.width - text_width - COLUMN_TITLES_HEIGHT; align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; break; case GTK_JUSTIFY_CENTER: @@ -6522,95 +5755,41 @@ 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 */ static void gtk_sheet_column_title_button_draw (GtkSheet *sheet, gint column) { - GdkWindow *window = NULL; GdkRectangle allocation; - + GtkSheetButton *button = NULL; gboolean is_sensitive = FALSE; if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (column >= 0 && ! xxx_column_is_visible (sheet, column)) return; - if (column >= 0 && !sheet->column_titles_visible) return; - if (column >= 0 && column < MIN_VISIBLE_COLUMN (sheet)) return; - if (column >= 0 && column > MAX_VISIBLE_COLUMN (sheet)) return; - - window = sheet->column_title_window; - allocation.y = 0; - allocation.height = sheet->column_title_area.height; + if (!sheet->column_titles_visible) return; + if (!g_sheet_column_get_visibility (sheet->column_geometry, column)) return; - 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; + if (column < MIN_VISIBLE_COLUMN (sheet)) return; + if (column > MAX_VISIBLE_COLUMN (sheet)) return; - gdk_window_clear_area (window, - allocation.x, allocation.y, - allocation.width, allocation.height); - } - else - { - GtkSheetButton *button = xxx_column_button (sheet, column); + button = g_sheet_column_get_button (sheet->column_geometry, column); + allocation.y = 0; allocation.x = COLUMN_LEFT_XPIXEL (sheet, column) + CELL_SPACING; - if (sheet->row_titles_visible) - allocation.x -= sheet->row_title_area.width; - - allocation.width = xxx_column_width (sheet, column); + allocation.x -= sheet->hadjustment->value; - is_sensitive = xxx_column_is_sensitive (sheet, column); - gtk_sheet_button_draw (sheet, window, button, - is_sensitive, allocation); - - /* FIXME: Not freeing this button is correct (sort of), - because in PSPP the model always returns a static copy */ - - /* gtk_sheet_button_free (button); */ + allocation.height = sheet->column_title_area.height; + allocation.width = g_sheet_column_get_width (sheet->column_geometry, column); + is_sensitive = g_sheet_column_get_sensitivity (sheet->column_geometry, column); + gtk_sheet_button_draw (sheet, sheet->column_title_window, + button, is_sensitive, allocation); } -} + static void gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row) { - GdkWindow *window = NULL; GdkRectangle allocation; GtkSheetButton *button = NULL; gboolean is_sensitive = FALSE; @@ -6618,23 +5797,23 @@ gtk_sheet_row_title_button_draw (GtkSheet *sheet, gint row) if (!GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) return; - if (row >= 0 && !yyy_row_is_visible (sheet, row)) return; - if (row >= 0 && !sheet->row_titles_visible) return; - if (row >= 0 && row < MIN_VISIBLE_ROW (sheet)) return; - if (row >= 0 && row > MAX_VISIBLE_ROW (sheet)) return; + if (!sheet->row_titles_visible) return; + if (!g_sheet_row_get_visibility (sheet->row_geometry, row)) return; + if (row < MIN_VISIBLE_ROW (sheet)) return; + if (row > MAX_VISIBLE_ROW (sheet)) return; - window = sheet->row_title_window; - button = yyy_row_button (sheet, row); + button = g_sheet_row_get_button (sheet->row_geometry, 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.y = g_sheet_row_start_pixel (sheet->row_geometry, row) + CELL_SPACING; + allocation.y -= sheet->vadjustment->value; + allocation.width = sheet->row_title_area.width; - allocation.height = yyy_row_height (sheet, row); - is_sensitive = yyy_row_is_sensitive (sheet, row); + allocation.height = g_sheet_row_get_height (sheet->row_geometry, row); + is_sensitive = g_sheet_row_get_sensitivity (sheet->row_geometry, row); - gtk_sheet_button_draw (sheet, window, button, is_sensitive, allocation); + gtk_sheet_button_draw (sheet, sheet->row_title_window, + button, is_sensitive, allocation); } /* SCROLLBARS @@ -6649,24 +5828,41 @@ 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->step_increment = + 1 ; // DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); + + sheet->vadjustment->page_increment = + sheet->sheet_window_height - DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)); + + sheet->vadjustment->upper = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)) + * g_sheet_row_get_row_count (sheet->row_geometry); + + sheet->vadjustment->lower = 0; - sheet->vadjustment->upper = SHEET_HEIGHT (sheet) + 80; - g_signal_emit_by_name (sheet->vadjustment, "changed"); + sheet->vadjustment->page_size = sheet->sheet_window_height; + g_signal_emit_by_name (sheet->vadjustment, "changed"); } if (sheet->hadjustment) { - sheet->hadjustment->page_size = sheet->sheet_window_width; - sheet->hadjustment->page_increment = sheet->sheet_window_width / 2; - sheet->hadjustment->step_increment = DEFAULT_COLUMN_WIDTH; + gint last_col; + sheet->hadjustment->step_increment = 1 ; //DEFAULT_COLUMN_WIDTH; + + sheet->hadjustment->page_increment = sheet->sheet_window_width ; + + last_col = g_sheet_column_get_column_count (sheet->column_geometry) - 1; + + sheet->hadjustment->upper = + g_sheet_column_start_pixel (sheet->column_geometry, last_col) + + + g_sheet_column_get_width (sheet->column_geometry, last_col) + ; + sheet->hadjustment->lower = 0; - sheet->hadjustment->upper = SHEET_WIDTH (sheet)+ 80; - g_signal_emit_by_name (sheet->hadjustment, "changed"); + sheet->hadjustment->page_size = sheet->sheet_window_width; + g_signal_emit_by_name (sheet->hadjustment, "changed"); } } @@ -6674,268 +5870,93 @@ static void vadjustment_value_changed (GtkAdjustment * adjustment, gpointer data) { - GtkSheet *sheet; - gint diff, value, old_value; - gint row, new_row; - gint y = 0; + 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; - - row = ROW_FROM_YPIXEL (sheet, CELL_SPACING); - - old_value = - sheet->voffset; - - new_row = g_sheet_row_pixel_to_row (sheet->row_geometry, - adjustment->value); - y = g_sheet_row_start_pixel (sheet->row_geometry, new_row); + if ( ! GTK_WIDGET_REALIZED (sheet)) return; - 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); - } - } + gtk_widget_hide (sheet->entry_widget); + gtk_sheet_range_draw (sheet, NULL); + size_allocate_row_title_buttons (sheet); + // size_allocate_global_button (sheet); +} - /* Negative old_adjustment enforces the redraw, otherwise avoid - spureous redraw */ - if (sheet->old_vadjustment >= 0. && row == new_row) - { - sheet->old_vadjustment = sheet->vadjustment->value; - return; - } - sheet->old_vadjustment = sheet->vadjustment->value; - adjustment->value = y; +static void +hadjustment_value_changed (GtkAdjustment * adjustment, + gpointer data) +{ + GtkSheet *sheet = GTK_SHEET (data); + g_return_if_fail (adjustment != NULL); - if (new_row == 0) - { - sheet->vadjustment->step_increment = yyy_row_height (sheet, 0); - } - else - { - sheet->vadjustment->step_increment = - MIN (yyy_row_height (sheet, new_row), yyy_row_height (sheet, new_row - 1)); - } + if ( ! GTK_WIDGET_REALIZED (sheet)) return; - sheet->vadjustment->value = adjustment->value; + gtk_widget_hide (sheet->entry_widget); + gtk_sheet_range_draw (sheet, NULL); + size_allocate_column_title_buttons (sheet); + // size_allocate_global_button (sheet); +} - value = adjustment->value; - if (value >= - sheet->voffset) - { - /* scroll down */ - diff = value + sheet->voffset; - } - else - { - /* scroll up */ - diff = - sheet->voffset - value; - } +/* COLUMN RESIZING */ +static void +draw_xor_vline (GtkSheet * sheet) +{ + gint xpos = sheet->x_drag; - sheet->voffset = - value; + if (sheet->row_titles_visible) + xpos += sheet->row_title_area.width; - 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; + gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc, + xpos, + sheet->column_title_area.height, + xpos, + sheet->sheet_window_height + CELL_SPACING); +} - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); +/* ROW RESIZING */ +static void +draw_xor_hline (GtkSheet * 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); - } +{ + gint ypos = sheet->y_drag; - gtk_sheet_position_children (sheet); + if (sheet->column_titles_visible) + ypos += sheet->column_title_area.height; - gtk_sheet_range_draw (sheet, NULL); - size_allocate_row_title_buttons (sheet); - size_allocate_global_button (sheet); + gdk_draw_line (GTK_WIDGET (sheet)->window, sheet->xor_gc, + sheet->row_title_area.width, + ypos, + sheet->sheet_window_width + CELL_SPACING, + ypos); } +/* SELECTED RANGE */ static void -hadjustment_value_changed (GtkAdjustment * adjustment, - gpointer data) +draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) { - GtkSheet *sheet; - gint i, diff, value, old_value; - gint column, new_column; - gint x = 0; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (GTK_IS_SHEET (data)); - - sheet = GTK_SHEET (data); + gint i = 0; + GdkRectangle clip_area, area; + GdkGCValues values; - if (GTK_SHEET_IS_FROZEN (sheet)) return; + area.x = COLUMN_LEFT_XPIXEL (sheet, range.col0); + area.y = g_sheet_row_start_pixel (sheet->row_geometry, range.row0); + area.width = COLUMN_LEFT_XPIXEL (sheet, range.coli)- area.x+ + g_sheet_column_get_width (sheet->column_geometry, range.coli); + area.height = g_sheet_row_start_pixel (sheet->row_geometry, range.rowi)- area.y + + g_sheet_row_get_height (sheet->row_geometry, range.rowi); - column = COLUMN_FROM_XPIXEL (sheet, CELL_SPACING); + 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; - old_value = - sheet->hoffset; + if (!sheet->row_titles_visible) clip_area.x = 0; + if (!sheet->column_titles_visible) clip_area.y = 0; - for (i = 0; i < xxx_column_count (sheet); i++) - { - if (xxx_column_is_visible (sheet, i)) x += xxx_column_width (sheet, i); - if (x > adjustment->value) break; - } - x -= xxx_column_width (sheet, i); - new_column = i; - - if (adjustment->value > sheet->old_hadjustment && sheet->old_hadjustment > 0 && - xxx_column_width (sheet, i) > sheet->hadjustment->step_increment) - { - /* This avoids embarrassing twitching */ - if (column == new_column && column != xxx_column_count (sheet) - 1 && - adjustment->value - sheet->old_hadjustment >= - sheet->hadjustment->step_increment && - new_column + 1 != MIN_VISIBLE_COLUMN (sheet)) - { - new_column += 1; - x += xxx_column_width (sheet, column); - } - } - - /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */ - if (sheet->old_hadjustment >= 0. && new_column == column) - { - sheet->old_hadjustment = sheet->hadjustment->value; - return; - } - - sheet->old_hadjustment = sheet->hadjustment->value; - adjustment->value = x; - - if (new_column == 0) - { - sheet->hadjustment->step_increment = xxx_column_width (sheet, 0); - } - else - { - sheet->hadjustment->step_increment = - MIN (xxx_column_width (sheet, new_column), xxx_column_width (sheet, new_column - 1)); - } - - - sheet->hadjustment->value = adjustment->value; - - value = adjustment->value; - - if (value >= - sheet->hoffset) - { - /* scroll right */ - diff = value + sheet->hoffset; - } - else - { - /* scroll left */ - diff = - sheet->hoffset - value; - } - - sheet->hoffset = - value; - if (GTK_WIDGET_REALIZED (sheet->entry_widget) && - sheet->state == GTK_SHEET_NORMAL && - sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 && - !gtk_sheet_cell_isvisible (sheet, sheet->active_cell.row, - sheet->active_cell.col)) - { - const gchar *text; - - text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet))); - if (!text || strlen (text) == 0) - gtk_sheet_cell_clear (sheet, - sheet->active_cell.row, - sheet->active_cell.col); - - gtk_widget_unmap (sheet->entry_widget); - } - - gtk_sheet_position_children (sheet); - - gtk_sheet_range_draw (sheet, NULL); - size_allocate_column_title_buttons (sheet); -} - - -/* COLUMN RESIZING */ -static void -draw_xor_vline (GtkSheet * sheet) -{ - GtkWidget *widget; - - g_return_if_fail (sheet != NULL); - - widget = GTK_WIDGET (sheet); - - gdk_draw_line (widget->window, sheet->xor_gc, - sheet->x_drag, - sheet->column_title_area.height, - sheet->x_drag, - sheet->sheet_window_height + 1); -} - -/* ROW RESIZING */ -static void -draw_xor_hline (GtkSheet * sheet) -{ - GtkWidget *widget; - - g_return_if_fail (sheet != NULL); - - widget = GTK_WIDGET (sheet); - - gdk_draw_line (widget->window, sheet->xor_gc, - sheet->row_title_area.width, - sheet->y_drag, - - sheet->sheet_window_width + 1, - sheet->y_drag); -} - -/* SELECTED RANGE */ -static void -draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) -{ - gint i; - GdkRectangle clip_area, area; - GdkGCValues values; - - area.x = COLUMN_LEFT_XPIXEL (sheet, range.col0); - area.y = ROW_TOP_YPIXEL (sheet, range.row0); - area.width = COLUMN_LEFT_XPIXEL (sheet, range.coli)- area.x+ - xxx_column_width (sheet, range.coli); - area.height = ROW_TOP_YPIXEL (sheet, range.rowi)- area.y+ - yyy_row_height (sheet, range.rowi); - - clip_area.x = sheet->row_title_area.width; - clip_area.y = sheet->column_title_area.height; - clip_area.width = sheet->sheet_window_width; - clip_area.height = sheet->sheet_window_height; - - if (!sheet->row_titles_visible) clip_area.x = 0; - if (!sheet->column_titles_visible) clip_area.y = 0; - - if (area.x < 0) + if (area.x < 0) { area.width = area.width + area.x; area.x = 0; @@ -6957,7 +5978,6 @@ 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, @@ -6968,38 +5988,29 @@ draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range) 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; - - cx = *x; + gint left_pos = COLUMN_LEFT_XPIXEL (sheet, column) + - sheet->hadjustment->value; - min_width = sheet->column_requisition; + gint width = *x - left_pos; - /* 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; + g_sheet_column_set_width (sheet->column_geometry, column, width); - xxx_set_column_width (sheet, column, width); size_allocate_column_title_buttons (sheet); return width; @@ -7009,30 +6020,28 @@ 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 < g_sheet_row_start_pixel (sheet->row_geometry, row) + min_height) { - *y = cy = ROW_TOP_YPIXEL (sheet, row) + min_height; + *y = cy = g_sheet_row_start_pixel (sheet->row_geometry, 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 - g_sheet_row_start_pixel (sheet->row_geometry, row)); if (height < min_height) height = min_height; - yyy_set_row_height (sheet, row, height); + g_sheet_row_set_height (sheet->row_geometry, row, height); size_allocate_row_title_buttons (sheet); return height; @@ -7048,15 +6057,15 @@ 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)) + if (column < 0 || column >= g_sheet_column_get_column_count (sheet->column_geometry)) return; gtk_sheet_column_size_request (sheet, column, &min_width); if (width < min_width) return; - xxx_set_column_width (sheet, column, width); + g_sheet_column_set_width (sheet->column_geometry, column, width); - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet)) + if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet))) { size_allocate_column_title_buttons (sheet); adjust_scrollbars (sheet); @@ -7079,15 +6088,15 @@ gtk_sheet_set_row_height (GtkSheet * sheet, 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 >= g_sheet_row_get_row_count (sheet->row_geometry)) return; gtk_sheet_row_size_request (sheet, row, &min_height); if (height < min_height) return; - yyy_set_row_height (sheet, row, height); + g_sheet_row_set_height (sheet->row_geometry, row, height); - if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) && !GTK_SHEET_IS_FROZEN (sheet)) + if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) ) { size_allocate_row_title_buttons (sheet); adjust_scrollbars (sheet); @@ -7152,7 +6161,7 @@ init_attributes (const GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes) colormap = gdk_colormap_get_system (); attributes->background = sheet->bg_color; } - attributes->justification = xxx_column_justification (sheet, col); + attributes->justification = g_sheet_column_get_justification (sheet->column_geometry, col); attributes->border.width = 0; attributes->border.line_style = GDK_LINE_SOLID; attributes->border.cap_style = GDK_CAP_NOT_LAST; @@ -7164,228 +6173,13 @@ init_attributes (const GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes) 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); - } - - return (child_info); -} - -void -gtk_sheet_attach_floating (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) -{ - GdkRectangle area; - GtkSheetChild *child; - - if (row < 0 || col < 0) - { - gtk_sheet_button_attach (sheet, widget, row, col); - return; - } - - gtk_sheet_get_cell_area (sheet, row, col, &area); - child = gtk_sheet_put (sheet, widget, area.x, area.y); - child->attached_to_cell = TRUE; - child->row = row; - child->col = col; -} - -void -gtk_sheet_attach_default (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) -{ - if (row < 0 || col < 0) - { - gtk_sheet_button_attach (sheet, widget, row, col); - return; - } - - gtk_sheet_attach (sheet, widget, row, col, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); -} - -void -gtk_sheet_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col, - gint xoptions, - gint yoptions, - gint xpadding, - gint ypadding) -{ - GdkRectangle area; - GtkSheetChild *child = NULL; - - if (row < 0 || col < 0) - { - gtk_sheet_button_attach (sheet, widget, row, col); - return; - } - - 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); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) && - !GTK_WIDGET_MAPPED (widget)) - gtk_widget_map (widget); - } - - gtk_sheet_position_child (sheet, child); - - /* This will avoid drawing on the titles */ - - 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); - } - -} - -void -gtk_sheet_button_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col) -{ - GtkSheetButton *button = 0; - GtkSheetChild *child; - GtkRequisition button_requisition; - - if (row >= 0 && col >= 0) return; - if (row < 0 && col < 0) return; - - 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; - - - sheet->children = g_list_append (sheet->children, child); - - gtk_sheet_button_size_request (sheet, button, &button_requisition); - - - 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); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (sheet)) && - !GTK_WIDGET_MAPPED (widget)) - gtk_widget_map (widget); - } - - if (row == -1) size_allocate_column_title_buttons (sheet); - if (col == -1) size_allocate_row_title_buttons (sheet); - -} - 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; + gint row_height = DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet)) - 2 * COLUMN_TITLES_HEIGHT + 2; req->height = 0; req->width = 0; @@ -7422,8 +6216,8 @@ gtk_sheet_button_size_request (GtkSheet *sheet, 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; + label_requisition.width += 2 * COLUMN_TITLES_HEIGHT; + label_requisition.height += 2 * COLUMN_TITLES_HEIGHT; } else { @@ -7431,19 +6225,9 @@ gtk_sheet_button_size_request (GtkSheet *sheet, label_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); @@ -7457,30 +6241,13 @@ 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_row_get_button (sheet->row_geometry, 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; } @@ -7490,8 +6257,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_column_get_button (sheet->column_geometry, col); gtk_sheet_button_size_request (sheet, button, @@ -7501,157 +6268,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, @@ -7659,23 +6278,10 @@ 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); @@ -7684,141 +6290,6 @@ gtk_sheet_forall (GtkContainer *container, } -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); -} - -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) { @@ -7836,7 +6307,6 @@ 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; @@ -7865,6 +6335,7 @@ append_cell_text (GString *string, const GtkSheet *sheet, gint r, gint c) g_free (celltext); } + static GString * range_to_text (const GtkSheet *sheet) { @@ -8002,4 +6473,3 @@ gtk_sheet_update_primary_selection (GtkSheet *sheet) gtk_clipboard_clear (clipboard); } } - diff --git a/lib/gtksheet/gtksheet.h b/lib/gtksheet/gtksheet.h index 4f402252..6aaa49a9 100644 --- a/lib/gtksheet/gtksheet.h +++ b/lib/gtksheet/gtksheet.h @@ -34,9 +34,7 @@ #include "gsheet-row-iface.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef enum @@ -69,13 +67,9 @@ enum #define GTK_SHEET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_sheet_get_type (), GtkSheetClass) #define GTK_IS_SHEET(obj) GTK_CHECK_TYPE (obj, gtk_sheet_get_type ()) -/* Public flags, for compatibility */ -#define GTK_SHEET_ROW_FROZEN(sheet) !gtk_sheet_rows_resizable (sheet) -#define GTK_SHEET_COLUMN_FROZEN(sheet) !gtk_sheet_columns_resizable (sheet) + #define GTK_SHEET_AUTORESIZE(sheet) gtk_sheet_autoresize (sheet) -#define GTK_SHEET_ROW_TITLES_VISIBLE(sheet) gtk_sheet_row_titles_visible (sheet) -#define GTK_SHEET_COL_TITLES_VISIBLE(sheet) gtk_sheet_column_titles_visible (sheet) #define GTK_SHEET_AUTO_SCROLL(sheet) gtk_sheet_autoscroll (sheet) #define GTK_SHEET_JUSTIFY_ENTRY(sheet) gtk_sheet_justify_entry (sheet) @@ -103,6 +97,7 @@ struct _GtkSheetCell gint col; }; + struct _GtkSheetHoverTitle { GtkWidget *window; @@ -112,8 +107,7 @@ struct _GtkSheetHoverTitle struct _GtkSheet { - GtkContainer container; - + GtkBin parent; gboolean dispose_has_run; GSheetColumn *column_geometry; @@ -133,9 +127,6 @@ struct _GtkSheet GdkColor grid_color; gboolean show_grid; - /* sheet children */ - GList *children; - /* allocation rectangle after the container_border_width and the width of the shadow border */ GdkRectangle internal_allocation; @@ -180,12 +171,6 @@ struct _GtkSheet /* sheet backing pixmap */ GdkPixmap *pixmap; - /* offsets for scrolling */ - gint hoffset; - gint voffset; - gfloat old_hadjustment; - gfloat old_vadjustment; - /* border shadow style */ GtkShadowType shadow_type; @@ -193,18 +178,20 @@ struct _GtkSheet GdkRectangle column_title_area; GdkWindow *column_title_window; gboolean column_titles_visible; + /* TRUE if the cursor is over the column title window */ + gboolean column_title_under; /* Row Titles */ GdkRectangle row_title_area; GdkWindow *row_title_window; gboolean row_titles_visible; + /* TRUE if the cursor is over the row title window */ + gboolean row_title_under; /*scrollbars*/ GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; - gint freeze_count; - /* xor GC for the verticle drag line */ GdkGC *xor_gc; @@ -233,7 +220,7 @@ struct _GtkSheet struct _GtkSheetClass { - GtkContainerClass parent_class; + GtkBinClass parent_class; void (*set_scroll_adjustments) (GtkSheet *sheet, GtkAdjustment *hadjustment, @@ -275,17 +262,6 @@ GtkType gtk_sheet_range_get_type (void); GtkWidget * gtk_sheet_new (GSheetRow *vgeo, GSheetColumn *hgeo, GSheetModel *model); - - - -/* create a new browser sheet. It cells can not be edited */ -GtkWidget * -gtk_sheet_new_browser (guint rows, guint columns, const gchar *title); - -void -gtk_sheet_construct_browser (GtkSheet *sheet, - guint rows, guint columns, const gchar *title); - /* create a new sheet with custom entry */ GtkWidget * gtk_sheet_new_with_custom_entry (GSheetRow *vgeo, @@ -296,202 +272,125 @@ gtk_sheet_construct_with_custom_entry (GtkSheet *sheet, GSheetRow *vgeo, GSheetColumn *hgeo, GtkType entry_type); -/* change scroll adjustments */ -void -gtk_sheet_set_hadjustment (GtkSheet *sheet, - GtkAdjustment *adjustment); -void -gtk_sheet_set_vadjustment (GtkSheet *sheet, - GtkAdjustment *adjustment); /* Change entry */ -void -gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type); +void gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type); -/* Returns sheet's entry widget */ -GtkWidget * -gtk_sheet_get_entry (GtkSheet *sheet); -GtkWidget * -gtk_sheet_get_entry_widget (GtkSheet *sheet); +GtkWidget *gtk_sheet_get_entry (GtkSheet *sheet); -/* Returns sheet->state - * Added by Steven Rostedt */ -gint -gtk_sheet_get_state (GtkSheet *sheet); -/* Returns sheet's ranges - * Added by Murray Cumming */ -guint -gtk_sheet_get_columns_count (GtkSheet *sheet); +guint gtk_sheet_get_columns_count (GtkSheet *sheet); -guint -gtk_sheet_get_rows_count (GtkSheet *sheet); +guint gtk_sheet_get_rows_count (GtkSheet *sheet); -void -gtk_sheet_get_visible_range (GtkSheet *sheet, +void gtk_sheet_get_selected_range (GtkSheet *sheet, GtkSheetRange *range); -void -gtk_sheet_get_selected_range (GtkSheet *sheet, - GtkSheetRange *range); +void gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode); -void -gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode); +void gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize); -void -gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize); +gboolean gtk_sheet_autoresize (GtkSheet *sheet); -gboolean -gtk_sheet_autoresize (GtkSheet *sheet); +void gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll); -void -gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll); +gboolean gtk_sheet_autoscroll (GtkSheet *sheet); -gboolean -gtk_sheet_autoscroll (GtkSheet *sheet); +void gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify); -void -gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify); +gboolean gtk_sheet_justify_entry (GtkSheet *sheet); -gboolean -gtk_sheet_justify_entry (GtkSheet *sheet); - -void -gtk_sheet_set_locked (GtkSheet *sheet, gboolean lock); - -gboolean -gtk_sheet_locked (const GtkSheet *sheet); - -/* set sheet title */ -void -gtk_sheet_set_title (GtkSheet *sheet, const gchar *title); - -/* freeze all visual updates of the sheet. - * Then thaw the sheet after you have made a number of changes. - * The updates will occure in a more efficent way than if - * you made them on a unfrozen sheet */ -void -gtk_sheet_freeze (GtkSheet *sheet); -void -gtk_sheet_thaw (GtkSheet *sheet); /* Background colors */ -void -gtk_sheet_set_background (GtkSheet *sheet, +void gtk_sheet_set_background (GtkSheet *sheet, GdkColor *bg_color); -void -gtk_sheet_set_grid (GtkSheet *sheet, + +void gtk_sheet_set_grid (GtkSheet *sheet, GdkColor *grid_color); -void -gtk_sheet_show_grid (GtkSheet *sheet, + +void gtk_sheet_show_grid (GtkSheet *sheet, gboolean show); -gboolean -gtk_sheet_grid_visible (GtkSheet *sheet); + +gboolean gtk_sheet_grid_visible (GtkSheet *sheet); /* set/get column title */ -void -gtk_sheet_set_column_title (GtkSheet * sheet, +void gtk_sheet_set_column_title (GtkSheet * sheet, gint column, const gchar * title); -const gchar * -gtk_sheet_get_column_title (GtkSheet * sheet, +const gchar *gtk_sheet_get_column_title (GtkSheet * sheet, gint column); /* set/get row title */ -void -gtk_sheet_set_row_title (GtkSheet * sheet, +void gtk_sheet_set_row_title (GtkSheet * sheet, gint row, const gchar * title); -const gchar * -gtk_sheet_get_row_title (GtkSheet * sheet, - gint row); +const gchar *gtk_sheet_get_row_title (GtkSheet * sheet, + gint row); /* set/get button label */ -void -gtk_sheet_row_button_add_label (GtkSheet *sheet, +void gtk_sheet_row_button_add_label (GtkSheet *sheet, gint row, const gchar *label); -const gchar * -gtk_sheet_row_button_get_label (GtkSheet *sheet, - gint row); -void -gtk_sheet_row_button_justify (GtkSheet *sheet, - gint row, GtkJustification justification); +const gchar *gtk_sheet_row_button_get_label (GtkSheet *sheet, + gint row); +void gtk_sheet_row_button_justify (GtkSheet *sheet, + gint row, GtkJustification justification); /* scroll the viewing area of the sheet to the given column * and row; row_align and col_align are between 0-1 representing the * location the row should appear on the screen, 0.0 being top or left, * 1.0 being bottom or right; if row or column is negative then there * is no change */ -void -gtk_sheet_moveto (GtkSheet *sheet, +void gtk_sheet_moveto (GtkSheet *sheet, gint row, gint column, gfloat row_align, gfloat col_align); -void -gtk_sheet_show_row_titles (GtkSheet *sheet); -void -gtk_sheet_hide_row_titles (GtkSheet *sheet); -void -gtk_sheet_show_column_titles (GtkSheet *sheet); -void -gtk_sheet_hide_column_titles (GtkSheet *sheet); +void gtk_sheet_show_row_titles (GtkSheet *sheet); +void gtk_sheet_hide_row_titles (GtkSheet *sheet); +void gtk_sheet_show_column_titles (GtkSheet *sheet); +void gtk_sheet_hide_column_titles (GtkSheet *sheet); -gboolean -gtk_sheet_row_titles_visible (GtkSheet *sheet); +gboolean gtk_sheet_row_titles_visible (GtkSheet *sheet); /* set row button sensitivity. If sensitivity is TRUE can be toggled, * otherwise it acts as a title */ -void -gtk_sheet_row_set_sensitivity (GtkSheet *sheet, +void gtk_sheet_row_set_sensitivity (GtkSheet *sheet, gint row, gboolean sensitive); /* set sensitivity for all row buttons */ -void -gtk_sheet_rows_set_sensitivity (GtkSheet *sheet, gboolean sensitive); -void -gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable); -gboolean -gtk_sheet_rows_resizable (GtkSheet *sheet); +void gtk_sheet_rows_set_sensitivity (GtkSheet *sheet, gboolean sensitive); +void gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable); +gboolean gtk_sheet_rows_resizable (GtkSheet *sheet); /* set row visibility. The default value is TRUE. If FALSE, the * row is hidden */ -void -gtk_sheet_row_set_visibility (GtkSheet *sheet, +void gtk_sheet_row_set_visibility (GtkSheet *sheet, gint row, gboolean visible); -void -gtk_sheet_row_label_set_visibility (GtkSheet *sheet, + +void gtk_sheet_row_label_set_visibility (GtkSheet *sheet, gint row, gboolean visible); -void -gtk_sheet_rows_labels_set_visibility (GtkSheet *sheet, gboolean visible); + +void gtk_sheet_rows_labels_set_visibility (GtkSheet *sheet, gboolean visible); /* select the row. The range is then highlighted, and the bounds are stored * in sheet->range */ -void -gtk_sheet_select_row (GtkSheet * sheet, - gint row); +void gtk_sheet_select_row (GtkSheet * sheet, gint row); /* select the column. The range is then highlighted, and the bounds are stored * in sheet->range */ -void -gtk_sheet_select_column (GtkSheet * sheet, - gint column); - -/* get scrollbars adjustment */ -GtkAdjustment * -gtk_sheet_get_vadjustment (GtkSheet * sheet); -GtkAdjustment * -gtk_sheet_get_hadjustment (GtkSheet * sheet); +void gtk_sheet_select_column (GtkSheet * sheet, gint column); /* highlight the selected range and store bounds in sheet->range */ -void gtk_sheet_select_range (GtkSheet *sheet, - const GtkSheetRange *range); +void gtk_sheet_select_range (GtkSheet *sheet, const GtkSheetRange *range); + +void gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range); + /* obvious */ void gtk_sheet_unselect_range (GtkSheet *sheet); @@ -499,112 +398,79 @@ void gtk_sheet_unselect_range (GtkSheet *sheet); /* set active cell where the entry will be displayed * returns FALSE if current cell can't be deactivated or * requested cell can't be activated */ -gboolean -gtk_sheet_set_active_cell (GtkSheet *sheet, +gboolean gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column); /* Sets *ROW and *COLUMN to be the coordinates of the active cell. ROW and/or COLUMN may be null if the caller is not interested in their values */ -void -gtk_sheet_get_active_cell (GtkSheet *sheet, +void gtk_sheet_get_active_cell (GtkSheet *sheet, gint *row, gint *column); -/* set cell contents and allocate memory if needed */ -void -gtk_sheet_set_cell (GtkSheet *sheet, - gint row, gint col, - GtkJustification justification, - const gchar *text); -void -gtk_sheet_set_cell_text (GtkSheet *sheet, - gint row, gint col, - const gchar *text); /* get cell contents */ -gchar * -gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col); +gchar *gtk_sheet_cell_get_text (const GtkSheet *sheet, gint row, gint col); /* clear cell contents */ -void -gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint col); +void gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint col); /* clear range contents. If range==NULL the whole sheet will be cleared */ -void -gtk_sheet_range_clear (GtkSheet *sheet, +void gtk_sheet_range_clear (GtkSheet *sheet, const GtkSheetRange *range); /* get cell state: GTK_STATE_NORMAL, GTK_STATE_SELECTED */ -GtkStateType -gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col); - -/* get row and column correspondig to the given position in the screen */ -gboolean -gtk_sheet_get_pixel_info (GtkSheet * sheet, - gint x, - gint y, - gint * row, - gint * column); +GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col); /* get area of a given cell */ -gboolean -gtk_sheet_get_cell_area (GtkSheet *sheet, +gboolean gtk_sheet_get_cell_area (GtkSheet *sheet, gint row, gint column, GdkRectangle *area); /* set row height */ -void -gtk_sheet_set_row_height (GtkSheet * sheet, +void gtk_sheet_set_row_height (GtkSheet * sheet, gint row, guint height); /* delete nrows rows starting in row */ -void -gtk_sheet_delete_rows (GtkSheet *sheet, guint row, guint nrows); +void gtk_sheet_delete_rows (GtkSheet *sheet, guint row, guint nrows); /* append nrows row to the end of the sheet */ -void -gtk_sheet_add_row (GtkSheet *sheet, guint nrows); +void gtk_sheet_add_row (GtkSheet *sheet, guint nrows); /* insert nrows rows before the given row and pull right */ -void -gtk_sheet_insert_rows (GtkSheet *sheet, guint row, guint nrows); +void gtk_sheet_insert_rows (GtkSheet *sheet, guint row, guint nrows); /* set abckground color of the given range */ -void -gtk_sheet_range_set_background (GtkSheet *sheet, +void gtk_sheet_range_set_background (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set foreground color (text color) of the given range */ -void -gtk_sheet_range_set_foreground (GtkSheet *sheet, +void gtk_sheet_range_set_foreground (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set text justification (GTK_JUSTIFY_LEFT, RIGHT, CENTER) of the given range. * The default value is GTK_JUSTIFY_LEFT. If autoformat is on, the * default justification for numbers is GTK_JUSTIFY_RIGHT */ -void -gtk_sheet_range_set_justification (GtkSheet *sheet, +void gtk_sheet_range_set_justification (GtkSheet *sheet, const GtkSheetRange *range, GtkJustification justification); -void -gtk_sheet_column_set_justification (GtkSheet *sheet, + +void gtk_sheet_column_set_justification (GtkSheet *sheet, gint column, GtkJustification justification); + /* set if cell contents can be edited or not in the given range: * accepted values are TRUE or FALSE. */ -void -gtk_sheet_range_set_editable (GtkSheet *sheet, +void gtk_sheet_range_set_editable (GtkSheet *sheet, const GtkSheetRange *range, gint editable); /* set if cell contents are visible or not in the given range: * accepted values are TRUE or FALSE.*/ -void -gtk_sheet_range_set_visible (GtkSheet *sheet, +void gtk_sheet_range_set_visible (GtkSheet *sheet, const GtkSheetRange *range, gboolean visible); @@ -613,80 +479,36 @@ gtk_sheet_range_set_visible (GtkSheet *sheet, * CELL_BOTTOM_BORDER * width is the width of the border line in pixels * line_style is the line_style for the border line */ -void -gtk_sheet_range_set_border (GtkSheet *sheet, +void gtk_sheet_range_set_border (GtkSheet *sheet, const GtkSheetRange *range, gint mask, guint width, gint line_style); /* set border color for the given range */ -void -gtk_sheet_range_set_border_color (GtkSheet *sheet, +void gtk_sheet_range_set_border_color (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set font for the given range */ -void -gtk_sheet_range_set_font (GtkSheet *sheet, +void gtk_sheet_range_set_font (GtkSheet *sheet, const GtkSheetRange *range, PangoFontDescription *font); /* get cell attributes of the given cell */ /* TRUE means that the cell is currently allocated */ -gboolean -gtk_sheet_get_attributes (const GtkSheet *sheet, +gboolean gtk_sheet_get_attributes (const GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *attributes); -GtkSheetChild * -gtk_sheet_put (GtkSheet *sheet, - GtkWidget *widget, - gint x, gint y); -void -gtk_sheet_attach_floating (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col); -void -gtk_sheet_attach_default (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col); -void -gtk_sheet_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col, - gint xoptions, - gint yoptions, - gint xpadding, - gint ypadding); - - -void -gtk_sheet_move_child (GtkSheet *sheet, - GtkWidget *widget, - gint x, gint y); - -GtkSheetChild * -gtk_sheet_get_child_at (GtkSheet *sheet, - gint row, gint col); - -void -gtk_sheet_button_attach (GtkSheet *sheet, - GtkWidget *widget, - gint row, gint col); - - - void gtk_sheet_set_model (GtkSheet *sheet, GSheetModel *model); GSheetModel * gtk_sheet_get_model (const GtkSheet *sheet); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __GTK_SHEET_H__ */ diff --git a/lib/gtksheet/gtkxpaned.c b/lib/gtksheet/gtkxpaned.c new file mode 100644 index 00000000..9aaea13c --- /dev/null +++ b/lib/gtksheet/gtkxpaned.c @@ -0,0 +1,3251 @@ +/******************************************************************************* +**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 +** 10 20 30 40 50 60 70 80 +** +** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+ +** Copyright (C) 2005-2006 Mirco "MacSlow" Müller +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License as published by the Free Software Foundation; either +** version 2.1 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public +** License along with this library; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +** +** GtkXPaned is based on GtkPaned which was done by... +** +** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald" +** +** and later modified by... +** +** "the GTK+ Team and others 1997-2000" +** +*******************************************************************************/ + +#include "gtkxpaned.h" +#include "gtkmarshalers.h" +#include +#include +#include +#include +#include + +enum WidgetProperties +{ + PROP_0, + PROP_X_POSITION, + PROP_Y_POSITION, + PROP_POSITION_SET, + PROP_MIN_X_POSITION, + PROP_MIN_Y_POSITION, + PROP_MAX_X_POSITION, + PROP_MAX_Y_POSITION +}; + +enum ChildProperties +{ + CHILD_PROP_0, + CHILD_PROP_RESIZE, + CHILD_PROP_SHRINK +}; + +enum WidgetSignals +{ + CYCLE_CHILD_FOCUS, + TOGGLE_HANDLE_FOCUS, + MOVE_HANDLE, + CYCLE_HANDLE_FOCUS, + ACCEPT_POSITION, + CANCEL_POSITION, + LAST_SIGNAL +}; + +static void gtk_xpaned_class_init (GtkXPanedClass* klass); + +static void gtk_xpaned_init (GtkXPaned* xpaned); + +static void gtk_xpaned_size_request (GtkWidget* widget, + GtkRequisition* requisition); + +static void gtk_xpaned_size_allocate (GtkWidget* widget, + GtkAllocation* allocation); + +static void gtk_xpaned_set_property (GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec); + +static void gtk_xpaned_get_property (GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec); + +static void gtk_xpaned_set_child_property (GtkContainer* container, + GtkWidget* child, + guint property_id, + const GValue* value, + GParamSpec* pspec); + +static void gtk_xpaned_get_child_property (GtkContainer* container, + GtkWidget* child, + guint property_id, + GValue* value, + GParamSpec* pspec); + +static void gtk_xpaned_finalize (GObject* object); + +static void gtk_xpaned_realize (GtkWidget* widget); + +static void gtk_xpaned_unrealize (GtkWidget* widget); + +static void gtk_xpaned_map (GtkWidget* widget); + +static void gtk_xpaned_unmap (GtkWidget* widget); + +static gboolean gtk_xpaned_expose (GtkWidget* widget, GdkEventExpose* event); + +static gboolean gtk_xpaned_enter (GtkWidget* widget, GdkEventCrossing* event); + +static gboolean gtk_xpaned_leave (GtkWidget* widget, GdkEventCrossing* event); + +static gboolean gtk_xpaned_button_press (GtkWidget* widget, + GdkEventButton* event); + +static gboolean gtk_xpaned_button_release (GtkWidget* widget, + GdkEventButton* event); + +static gboolean gtk_xpaned_motion (GtkWidget* widget, GdkEventMotion* event); + +static gboolean gtk_xpaned_focus (GtkWidget* widget, + GtkDirectionType direction); + +static void gtk_xpaned_add (GtkContainer* container, GtkWidget* widget); + +static void gtk_xpaned_remove (GtkContainer* container, GtkWidget* widget); + +static void gtk_xpaned_forall (GtkContainer* container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +static void gtk_xpaned_set_focus_child (GtkContainer* container, + GtkWidget* child); + +static void gtk_xpaned_set_saved_focus (GtkXPaned* xpaned, GtkWidget* widget); + +static void gtk_xpaned_set_first_xpaned (GtkXPaned* xpaned, + GtkXPaned* first_xpaned); + +static void gtk_xpaned_set_last_top_left_child_focus (GtkXPaned* xpaned, + GtkWidget* widget); + +static void gtk_xpaned_set_last_top_right_child_focus (GtkXPaned* xpaned, + GtkWidget* widget); + +static void gtk_xpaned_set_last_bottom_left_child_focus (GtkXPaned* xpaned, + GtkWidget* widget); + +static void gtk_xpaned_set_last_bottom_right_child_focus (GtkXPaned* xpaned, + GtkWidget* widget); + +static gboolean gtk_xpaned_cycle_child_focus (GtkXPaned* xpaned, + gboolean reverse); + +static gboolean gtk_xpaned_cycle_handle_focus (GtkXPaned* xpaned, + gboolean reverse); + +static gboolean gtk_xpaned_move_handle (GtkXPaned* xpaned, + GtkScrollType scroll); + +static gboolean gtk_xpaned_accept_position (GtkXPaned* xpaned); + +static gboolean gtk_xpaned_cancel_position (GtkXPaned* xpaned); + +static gboolean gtk_xpaned_toggle_handle_focus (GtkXPaned* xpaned); + +static GType gtk_xpaned_child_type (GtkContainer* container); + +static GtkContainerClass* parent_class = NULL; + +struct _GtkXPanedPrivate +{ + GtkWidget *saved_focus; + GtkXPaned *first_xpaned; +}; + +GType gtk_xpaned_get_type (void) +{ + static GType xpaned_type = 0; + + if (!xpaned_type) + { + static const GTypeInfo xpaned_info = + { + sizeof (GtkXPanedClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gtk_xpaned_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkXPaned), + 0, /* n_preallocs */ + (GInstanceInitFunc) gtk_xpaned_init + }; + + xpaned_type = g_type_register_static (GTK_TYPE_CONTAINER, + "GtkXPaned", + &xpaned_info, + 0); + } + + return xpaned_type; +} + +GtkWidget* gtk_xpaned_new (void) +{ + GtkXPaned* xpaned; + + xpaned = g_object_new (GTK_TYPE_XPANED, NULL); + + return GTK_WIDGET (xpaned); +} + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void add_tab_bindings (GtkBindingSet* binding_set, + GdkModifierType modifiers) +{ + gtk_binding_entry_add_signal (binding_set, + GDK_Tab, + modifiers, + "toggle_handle_focus", + 0); + + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Tab, + modifiers, + "toggle_handle_focus", + 0); +} + +static void add_move_binding (GtkBindingSet* binding_set, + guint keyval, + GdkModifierType mask, + GtkScrollType scroll) +{ + gtk_binding_entry_add_signal (binding_set, + keyval, + mask, + "move_handle", + 1, + GTK_TYPE_SCROLL_TYPE, + scroll); +} + +static void gtk_xpaned_class_init (GtkXPanedClass* class) +{ + GObjectClass* object_class; + GtkWidgetClass* widget_class; + GtkContainerClass* container_class; + GtkXPanedClass* xpaned_class; + GtkBindingSet* binding_set; + + object_class = (GObjectClass *) class; + widget_class = (GtkWidgetClass *) class; + container_class = (GtkContainerClass *) class; + xpaned_class = (GtkXPanedClass *) class; + + parent_class = g_type_class_peek_parent (class); + + object_class->set_property = gtk_xpaned_set_property; + object_class->get_property = gtk_xpaned_get_property; + object_class->finalize = gtk_xpaned_finalize; + + widget_class->realize = gtk_xpaned_realize; + widget_class->unrealize = gtk_xpaned_unrealize; + widget_class->map = gtk_xpaned_map; + widget_class->unmap = gtk_xpaned_unmap; + widget_class->expose_event = gtk_xpaned_expose; + widget_class->focus = gtk_xpaned_focus; + widget_class->enter_notify_event = gtk_xpaned_enter; + widget_class->leave_notify_event = gtk_xpaned_leave; + widget_class->button_press_event = gtk_xpaned_button_press; + widget_class->button_release_event = gtk_xpaned_button_release; + widget_class->motion_notify_event = gtk_xpaned_motion; + widget_class->size_request = gtk_xpaned_size_request; + widget_class->size_allocate = gtk_xpaned_size_allocate; + + container_class->add = gtk_xpaned_add; + container_class->remove = gtk_xpaned_remove; + container_class->forall = gtk_xpaned_forall; + container_class->child_type = gtk_xpaned_child_type; + container_class->set_focus_child = gtk_xpaned_set_focus_child; + container_class->set_child_property = gtk_xpaned_set_child_property; + container_class->get_child_property = gtk_xpaned_get_child_property; + + xpaned_class->cycle_child_focus = gtk_xpaned_cycle_child_focus; + xpaned_class->toggle_handle_focus = gtk_xpaned_toggle_handle_focus; + xpaned_class->move_handle = gtk_xpaned_move_handle; + xpaned_class->cycle_handle_focus = gtk_xpaned_cycle_handle_focus; + xpaned_class->accept_position = gtk_xpaned_accept_position; + xpaned_class->cancel_position = gtk_xpaned_cancel_position; + + g_object_class_install_property (object_class, + PROP_X_POSITION, + g_param_spec_int ("x-position", + ("x-Position"), + ("x-Position of paned separator in pixels (0 means all the way to the left)"), + 0, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property (object_class, + PROP_Y_POSITION, + g_param_spec_int ("y-position", + "y-Position", + "y-Position of paned separator in pixels (0 means all the way to the top)", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property (object_class, + PROP_POSITION_SET, + g_param_spec_boolean ("position-set", + "Position Set", + "TRUE if the Position property should be used", + FALSE, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_int ("handle-size", + "Handle Size", + "Width of handle", + 0, + G_MAXINT, + 3, + G_PARAM_READABLE)); + /** + * GtkXPaned:min-x-position: + * + * The smallest possible value for the x-position property. This property is derived from the + * size and shrinkability of the widget's children. + * + * Since: 2.4 + */ + g_object_class_install_property (object_class, + PROP_MIN_X_POSITION, + g_param_spec_int ("min-x-position", + "Minimal x-Position", + "Smallest possible value for the \"x-position\" property", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + + /** + * GtkXPaned:min-y-position: + * + * The smallest possible value for the y-position property. This property is derived from the + * size and shrinkability of the widget's children. + * + * Since: 2.4 + */ + g_object_class_install_property (object_class, + PROP_MIN_Y_POSITION, + g_param_spec_int ("min-y-position", + "Minimal y-Position", + "Smallest possible value for the \"y-position\" property", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + + /** + * GtkPaned:max-x-position: + * + * The largest possible value for the x-position property. This property is derived from the + * size and shrinkability of the widget's children. + * + * Since: 2.4 + */ + g_object_class_install_property (object_class, + PROP_MAX_X_POSITION, + g_param_spec_int ("max-x-position", + "Maximal x-Position", + "Largest possible value for the \"x-position\" property", + 0, + G_MAXINT, + G_MAXINT, + G_PARAM_READABLE)); + + /** + * GtkPaned:max-y-position: + * + * The largest possible value for the y-position property. This property is derived from the + * size and shrinkability of the widget's children. + * + * Since: 2.4 + */ + g_object_class_install_property (object_class, + PROP_MAX_Y_POSITION, + g_param_spec_int ("max-y-position", + "Maximal y-Position", + "Largest possible value for the \"y-position\" property", + 0, + G_MAXINT, + G_MAXINT, + G_PARAM_READABLE)); + + /** + * GtkPaned:resize: + * + * The "resize" child property determines whether the child expands and + * shrinks along with the paned widget. + * + * Since: 2.4 + */ + gtk_container_class_install_child_property (container_class, + CHILD_PROP_RESIZE, + g_param_spec_boolean ("resize", + "Resize", + "If TRUE, the child expands and shrinks along with the paned widget", + TRUE, + G_PARAM_READWRITE)); + + /** + * GtkPaned:shrink: + * + * The "shrink" child property determines whether the child can be made + * smaller than its requisition. + * + * Since: 2.4 + */ + gtk_container_class_install_child_property (container_class, + CHILD_PROP_SHRINK, + g_param_spec_boolean ("shrink", + "Shrink", + "If TRUE, the child can be made smaller than its requisition", + TRUE, + G_PARAM_READWRITE)); + + signals [CYCLE_CHILD_FOCUS] = g_signal_new ("cycle-child-focus", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, cycle_child_focus), + NULL, NULL, + gtk_marshal_BOOLEAN__BOOLEAN, + G_TYPE_BOOLEAN, 1, + G_TYPE_BOOLEAN); + + signals [TOGGLE_HANDLE_FOCUS] = g_signal_new ("toggle-handle-focus", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, toggle_handle_focus), + NULL, NULL, + gtk_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + signals[MOVE_HANDLE] = g_signal_new ("move-handle", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, move_handle), + NULL, NULL, + gtk_marshal_BOOLEAN__ENUM, + G_TYPE_BOOLEAN, 1, + GTK_TYPE_SCROLL_TYPE); + + signals [CYCLE_HANDLE_FOCUS] = g_signal_new ("cycle-handle-focus", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, cycle_handle_focus), + NULL, NULL, + gtk_marshal_BOOLEAN__BOOLEAN, + G_TYPE_BOOLEAN, 1, + G_TYPE_BOOLEAN); + + signals [ACCEPT_POSITION] = g_signal_new ("accept-position", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, accept_position), + NULL, NULL, + gtk_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + signals [CANCEL_POSITION] = g_signal_new ("cancel-position", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkXPanedClass, cancel_position), + NULL, NULL, + gtk_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + binding_set = gtk_binding_set_by_class (class); + + /* F6 and friends */ + gtk_binding_entry_add_signal (binding_set, + GDK_F6, 0, + "cycle-child-focus", 1, + G_TYPE_BOOLEAN, FALSE); + + gtk_binding_entry_add_signal (binding_set, + GDK_F6, GDK_SHIFT_MASK, + "cycle-child-focus", 1, + G_TYPE_BOOLEAN, TRUE); + + /* F8 and friends */ + gtk_binding_entry_add_signal (binding_set, + GDK_F8, 0, + "cycle-handle-focus", 1, + G_TYPE_BOOLEAN, FALSE); + + gtk_binding_entry_add_signal (binding_set, + GDK_F8, GDK_SHIFT_MASK, + "cycle-handle-focus", 1, + G_TYPE_BOOLEAN, TRUE); + + add_tab_bindings (binding_set, 0); + add_tab_bindings (binding_set, GDK_CONTROL_MASK); + add_tab_bindings (binding_set, GDK_SHIFT_MASK); + add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK); + + /* accept and cancel positions */ + gtk_binding_entry_add_signal (binding_set, + GDK_Escape, 0, + "cancel-position", 0); + + gtk_binding_entry_add_signal (binding_set, + GDK_Return, 0, + "accept-position", 0); + + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Enter, 0, + "accept-position", 0); + + gtk_binding_entry_add_signal (binding_set, + GDK_space, 0, + "accept-position", 0); + + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Space, 0, + "accept-position", 0); + + /* move handle */ + add_move_binding (binding_set, GDK_Left, 0, GTK_SCROLL_STEP_LEFT); + add_move_binding (binding_set, GDK_KP_Left, 0, GTK_SCROLL_STEP_LEFT); + add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_LEFT); + add_move_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_LEFT); + + add_move_binding (binding_set, GDK_Right, 0, GTK_SCROLL_STEP_RIGHT); + add_move_binding (binding_set, GDK_Right, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_RIGHT); + add_move_binding (binding_set, GDK_KP_Right, 0, GTK_SCROLL_STEP_RIGHT); + add_move_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_RIGHT); + + add_move_binding (binding_set, GDK_Up, 0, GTK_SCROLL_STEP_UP); + add_move_binding (binding_set, GDK_Up, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_UP); + add_move_binding (binding_set, GDK_KP_Up, 0, GTK_SCROLL_STEP_UP); + add_move_binding (binding_set, GDK_KP_Up, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_UP); + add_move_binding (binding_set, GDK_Page_Up, 0, GTK_SCROLL_PAGE_UP); + add_move_binding (binding_set, GDK_KP_Page_Up, 0, GTK_SCROLL_PAGE_UP); + + add_move_binding (binding_set, GDK_Down, 0, GTK_SCROLL_STEP_DOWN); + add_move_binding (binding_set, GDK_Down, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_DOWN); + add_move_binding (binding_set, GDK_KP_Down, 0, GTK_SCROLL_STEP_DOWN); + add_move_binding (binding_set, GDK_KP_Down, GDK_CONTROL_MASK, GTK_SCROLL_PAGE_DOWN); + add_move_binding (binding_set, GDK_Page_Down, 0, GTK_SCROLL_PAGE_RIGHT); + add_move_binding (binding_set, GDK_KP_Page_Down, 0, GTK_SCROLL_PAGE_RIGHT); + + add_move_binding (binding_set, GDK_Home, 0, GTK_SCROLL_START); + add_move_binding (binding_set, GDK_KP_Home, 0, GTK_SCROLL_START); + add_move_binding (binding_set, GDK_End, 0, GTK_SCROLL_END); + add_move_binding (binding_set, GDK_KP_End, 0, GTK_SCROLL_END); +} + +static GType gtk_xpaned_child_type (GtkContainer* container) +{ + if (!GTK_XPANED (container)->top_left_child || + !GTK_XPANED (container)->top_right_child || + !GTK_XPANED (container)->bottom_left_child || + !GTK_XPANED (container)->bottom_right_child) + return GTK_TYPE_WIDGET; + else + return G_TYPE_NONE; +} + +static void gtk_xpaned_init (GtkXPaned* xpaned) +{ + GTK_WIDGET_SET_FLAGS (xpaned, GTK_NO_WINDOW | GTK_CAN_FOCUS); + + xpaned->top_left_child = NULL; + xpaned->top_right_child = NULL; + xpaned->bottom_left_child = NULL; + xpaned->bottom_right_child = NULL; + xpaned->handle_east = NULL; + xpaned->handle_west = NULL; + xpaned->handle_north = NULL; + xpaned->handle_south = NULL; + xpaned->handle_middle = NULL; + xpaned->xor_gc = NULL; + xpaned->cursor_type_east = GDK_SB_V_DOUBLE_ARROW; + xpaned->cursor_type_west = GDK_SB_V_DOUBLE_ARROW; + xpaned->cursor_type_north = GDK_SB_H_DOUBLE_ARROW; + xpaned->cursor_type_south = GDK_SB_H_DOUBLE_ARROW; + xpaned->cursor_type_middle = GDK_FLEUR; + + xpaned->handle_pos_east.width = 5; + xpaned->handle_pos_east.height = 5; + xpaned->handle_pos_west.width = 5; + xpaned->handle_pos_west.height = 5; + xpaned->handle_pos_north.width = 5; + xpaned->handle_pos_north.height = 5; + xpaned->handle_pos_south.width = 5; + xpaned->handle_pos_south.height = 5; + xpaned->handle_pos_middle.width = 5; + xpaned->handle_pos_middle.height = 5; + + xpaned->position_set = FALSE; + xpaned->last_allocation.width = -1; + xpaned->last_allocation.height = -1; + xpaned->in_drag_vert = FALSE; + xpaned->in_drag_horiz = FALSE; + xpaned->in_drag_vert_and_horiz = FALSE; + + xpaned->maximized[GTK_XPANED_TOP_LEFT] = FALSE; + xpaned->maximized[GTK_XPANED_TOP_RIGHT] = FALSE; + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = FALSE; + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = FALSE; + + xpaned->priv = g_new0 (GtkXPanedPrivate, 1); + xpaned->last_top_left_child_focus = NULL; + xpaned->last_top_right_child_focus = NULL; + xpaned->last_bottom_left_child_focus = NULL; + xpaned->last_bottom_right_child_focus = NULL; + xpaned->in_recursion = FALSE; + xpaned->handle_prelit = FALSE; + xpaned->original_position.x = -1; + xpaned->original_position.y = -1; + xpaned->unmaximized_position.x = -1; + xpaned->unmaximized_position.y = -1; + + xpaned->handle_pos_east.x = -1; + xpaned->handle_pos_east.y = -1; + xpaned->handle_pos_west.x = -1; + xpaned->handle_pos_west.y = -1; + xpaned->handle_pos_north.x = -1; + xpaned->handle_pos_north.y = -1; + xpaned->handle_pos_south.x = -1; + xpaned->handle_pos_south.y = -1; + xpaned->handle_pos_middle.x = -1; + xpaned->handle_pos_middle.y = -1; + + xpaned->drag_pos.x = -1; + xpaned->drag_pos.y = -1; +} + +static void gtk_xpaned_size_request (GtkWidget* widget, + GtkRequisition* requisition) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + GtkRequisition child_requisition; + + requisition->width = 0; + requisition->height = 0; + + if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child)) + { + gtk_widget_size_request (xpaned->top_left_child, &child_requisition); + + requisition->width = child_requisition.width; + requisition->height = child_requisition.height; + } + + if (xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child)) + { + gtk_widget_size_request (xpaned->top_right_child, &child_requisition); + + requisition->width += child_requisition.width; + requisition->height = MAX (requisition->height, child_requisition.height); + } + + if (xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child)) + { + gtk_widget_size_request (xpaned->bottom_left_child, &child_requisition); + + requisition->width = MAX (requisition->width, child_requisition.width); + requisition->height += child_requisition.height; + } + + if (xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child)) + { + gtk_widget_size_request (xpaned->bottom_right_child, &child_requisition); + + requisition->width = MAX (requisition->width, child_requisition.width); + requisition->height = MAX (requisition->height, child_requisition.height); + } + + /* add 2 times the set border-width to the GtkXPaneds requisition */ + requisition->width += GTK_CONTAINER (xpaned)->border_width * 2; + requisition->height += GTK_CONTAINER (xpaned)->border_width * 2; + + /* also add the handle "thickness" to GtkXPaneds width- and height-requisitions */ + if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) && + xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) && + xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) && + xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child)) + { + gint handle_size; + + gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); + requisition->width += handle_size; + requisition->height += handle_size; + } +} + +static void gtk_xpaned_size_allocate (GtkWidget* widget, + GtkAllocation* allocation) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + gint border_width = GTK_CONTAINER (xpaned)->border_width; + GtkAllocation top_left_child_allocation; + GtkAllocation top_right_child_allocation; + GtkAllocation bottom_left_child_allocation; + GtkAllocation bottom_right_child_allocation; + GtkRequisition top_left_child_requisition; + GtkRequisition top_right_child_requisition; + GtkRequisition bottom_left_child_requisition; + GtkRequisition bottom_right_child_requisition; + gint handle_size; + + /* determine size of handle(s) */ + gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); + + widget->allocation = *allocation; + + if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) && + xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) && + xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) && + xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child)) + { + /* what sizes do the children want to be at least at */ + gtk_widget_get_child_requisition (xpaned->top_left_child, + &top_left_child_requisition); + gtk_widget_get_child_requisition (xpaned->top_right_child, + &top_right_child_requisition); + gtk_widget_get_child_requisition (xpaned->bottom_left_child, + &bottom_left_child_requisition); + gtk_widget_get_child_requisition (xpaned->bottom_right_child, + &bottom_right_child_requisition); + + /* determine the total requisition-sum of all requisitions of borders, + * handles, children etc. */ + gtk_xpaned_compute_position (xpaned, + allocation, + &top_left_child_requisition, + &top_right_child_requisition, + &bottom_left_child_requisition, + &bottom_right_child_requisition); + + /* calculate the current positions and sizes of the handles */ + xpaned->handle_pos_east.x = widget->allocation.x + border_width + xpaned->top_left_child_size.width + handle_size; + xpaned->handle_pos_east.y = widget->allocation.y + border_width + xpaned->top_left_child_size.height; + xpaned->handle_pos_east.width = widget->allocation.width - xpaned->top_left_child_size.width - 2 * border_width - handle_size; + xpaned->handle_pos_east.height = handle_size; + + xpaned->handle_pos_west.x = widget->allocation.x + border_width; + xpaned->handle_pos_west.y = xpaned->handle_pos_east.y; + xpaned->handle_pos_west.width = widget->allocation.width - xpaned->handle_pos_east.width - 2 * border_width - handle_size; + xpaned->handle_pos_west.height = handle_size; + + xpaned->handle_pos_north.x = xpaned->handle_pos_east.x - handle_size; + xpaned->handle_pos_north.y = widget->allocation.y + border_width; + xpaned->handle_pos_north.width = handle_size; + xpaned->handle_pos_north.height = xpaned->handle_pos_east.y - widget->allocation.y - border_width; + + xpaned->handle_pos_south.x = xpaned->handle_pos_north.x; + xpaned->handle_pos_south.y = xpaned->handle_pos_east.y + handle_size; + xpaned->handle_pos_south.width = handle_size; + xpaned->handle_pos_south.height = widget->allocation.height - xpaned->handle_pos_north.height - 2 * border_width - handle_size; + + +#define CENTRUM 20 + xpaned->handle_pos_middle.x = xpaned->handle_pos_north.x ; + xpaned->handle_pos_middle.y = xpaned->handle_pos_east.y ; + xpaned->handle_pos_middle.width = handle_size + CENTRUM ; + xpaned->handle_pos_middle.height = handle_size + CENTRUM; + + /* set allocation for top-left child */ + top_left_child_allocation.x = widget->allocation.x + border_width; + top_left_child_allocation.y = widget->allocation.y + border_width; + top_left_child_allocation.width = xpaned->handle_pos_west.width; + top_left_child_allocation.height = xpaned->handle_pos_north.height; + + /* set allocation for top-right child */ + top_right_child_allocation.x = widget->allocation.x + border_width + handle_size + top_left_child_allocation.width; + top_right_child_allocation.y = widget->allocation.y + border_width; + top_right_child_allocation.width = xpaned->handle_pos_east.width; + top_right_child_allocation.height = xpaned->handle_pos_north.height; + + /* set allocation for bottom-left child */ + bottom_left_child_allocation.x = xpaned->handle_pos_west.x; + bottom_left_child_allocation.y = xpaned->handle_pos_south.y; + bottom_left_child_allocation.width = xpaned->handle_pos_west.width; + bottom_left_child_allocation.height = xpaned->handle_pos_south.height; + + /* set allocation for bottom-right child */ + bottom_right_child_allocation.x = top_right_child_allocation.x; + bottom_right_child_allocation.y = bottom_left_child_allocation.y; + bottom_right_child_allocation.width = xpaned->handle_pos_east.width; + bottom_right_child_allocation.height = xpaned->handle_pos_south.height; + + if (GTK_WIDGET_REALIZED (widget)) + { + if (GTK_WIDGET_MAPPED (widget)) + { + gdk_window_show (xpaned->handle_east); + gdk_window_show (xpaned->handle_west); + gdk_window_show (xpaned->handle_north); + gdk_window_show (xpaned->handle_south); + gdk_window_show (xpaned->handle_middle); + } + + gdk_window_move_resize (xpaned->handle_east, + xpaned->handle_pos_east.x, + xpaned->handle_pos_east.y, + xpaned->handle_pos_east.width, + xpaned->handle_pos_east.height); + + gdk_window_move_resize (xpaned->handle_west, + xpaned->handle_pos_west.x, + xpaned->handle_pos_west.y, + xpaned->handle_pos_west.width, + xpaned->handle_pos_west.height); + + gdk_window_move_resize (xpaned->handle_north, + xpaned->handle_pos_north.x, + xpaned->handle_pos_north.y, + xpaned->handle_pos_north.width, + xpaned->handle_pos_north.height); + + gdk_window_move_resize (xpaned->handle_south, + xpaned->handle_pos_south.x, + xpaned->handle_pos_south.y, + xpaned->handle_pos_south.width, + xpaned->handle_pos_south.height); + + gdk_window_move_resize (xpaned->handle_middle, + xpaned->handle_pos_middle.x, + xpaned->handle_pos_middle.y, + xpaned->handle_pos_middle.width, + xpaned->handle_pos_middle.height); + } + + /* Now allocate the childen, making sure, when resizing not to + * overlap the windows + */ + if (GTK_WIDGET_MAPPED (widget)) + { + gtk_widget_size_allocate (xpaned->top_right_child, &top_right_child_allocation); + gtk_widget_size_allocate (xpaned->top_left_child, &top_left_child_allocation); + gtk_widget_size_allocate (xpaned->bottom_left_child, &bottom_left_child_allocation); + gtk_widget_size_allocate (xpaned->bottom_right_child, &bottom_right_child_allocation); + } + } +} + +static void gtk_xpaned_set_property (GObject* object, + guint prop_id, + const GValue* value, + GParamSpec* pspec) +{ + GtkXPaned* xpaned = GTK_XPANED (object); + + switch (prop_id) + { + case PROP_X_POSITION: + gtk_xpaned_set_position_x (xpaned, g_value_get_int (value)); + break; + + case PROP_Y_POSITION: + gtk_xpaned_set_position_y (xpaned, g_value_get_int (value)); + break; + + case PROP_POSITION_SET: + xpaned->position_set = g_value_get_boolean (value); + gtk_widget_queue_resize (GTK_WIDGET (xpaned)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gtk_xpaned_get_property (GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec) +{ + GtkXPaned* xpaned = GTK_XPANED (object); + + switch (prop_id) + { + case PROP_X_POSITION: + g_value_set_int (value, xpaned->top_left_child_size.width); + break; + + case PROP_Y_POSITION: + g_value_set_int (value, xpaned->top_left_child_size.height); + break; + + case PROP_POSITION_SET: + g_value_set_boolean (value, xpaned->position_set); + break; + + case PROP_MIN_X_POSITION: + g_value_set_int (value, xpaned->min_position.x); + break; + + case PROP_MIN_Y_POSITION: + g_value_set_int (value, xpaned->min_position.y); + break; + + case PROP_MAX_X_POSITION: + g_value_set_int (value, xpaned->max_position.x); + break; + + case PROP_MAX_Y_POSITION: + g_value_set_int (value, xpaned->max_position.y); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gtk_xpaned_set_child_property (GtkContainer* container, + GtkWidget* child, + guint property_id, + const GValue* value, + GParamSpec* pspec) +{ + GtkXPaned* xpaned = GTK_XPANED (container); + gboolean old_value = FALSE; + gboolean new_value = FALSE; + + g_assert (child == xpaned->top_left_child || + child == xpaned->top_right_child || + child == xpaned->bottom_left_child || + child == xpaned->bottom_right_child); + + new_value = g_value_get_boolean (value); + + switch (property_id) + { + case CHILD_PROP_RESIZE: + if (child == xpaned->top_left_child) + { + old_value = xpaned->top_left_child_resize; + xpaned->top_left_child_resize = new_value; + } + else if (child == xpaned->top_right_child) + { + old_value = xpaned->top_right_child_resize; + xpaned->top_right_child_resize = new_value; + } + else if (child == xpaned->bottom_left_child) + { + old_value = xpaned->bottom_left_child_resize; + xpaned->bottom_left_child_resize = new_value; + } + else if (child == xpaned->bottom_right_child) + { + old_value = xpaned->bottom_right_child_resize; + xpaned->bottom_right_child_resize = new_value; + } + break; + + case CHILD_PROP_SHRINK : + if (child == xpaned->top_left_child) + { + old_value = xpaned->top_left_child_shrink; + xpaned->top_left_child_shrink = new_value; + } + else if (child == xpaned->top_right_child) + { + old_value = xpaned->top_right_child_shrink; + xpaned->top_right_child_shrink = new_value; + } + else if (child == xpaned->bottom_left_child) + { + old_value = xpaned->bottom_left_child_shrink; + xpaned->bottom_left_child_shrink = new_value; + } + else if (child == xpaned->bottom_right_child) + { + old_value = xpaned->bottom_right_child_shrink; + xpaned->bottom_right_child_shrink = new_value; + } + break; + + default: + GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, + property_id, + pspec); + old_value = -1; /* quiet gcc */ + break; + } + + if (old_value != new_value) + gtk_widget_queue_resize (GTK_WIDGET (container)); +} + +static void gtk_xpaned_get_child_property (GtkContainer* container, + GtkWidget* child, + guint property_id, + GValue* value, + GParamSpec* pspec) +{ + GtkXPaned* xpaned = GTK_XPANED (container); + + g_assert (child == xpaned->top_left_child || + child == xpaned->top_right_child || + child == xpaned->bottom_left_child || + child == xpaned->bottom_right_child); + + switch (property_id) + { + case CHILD_PROP_RESIZE : + if (child == xpaned->top_left_child) + g_value_set_boolean (value, xpaned->top_left_child_resize); + else if (child == xpaned->top_right_child) + g_value_set_boolean (value, xpaned->top_right_child_resize); + else if (child == xpaned->bottom_left_child) + g_value_set_boolean (value, xpaned->bottom_left_child_resize); + else if (child == xpaned->bottom_right_child) + g_value_set_boolean (value, xpaned->bottom_right_child_resize); + break; + + case CHILD_PROP_SHRINK : + if (child == xpaned->top_left_child) + g_value_set_boolean (value, xpaned->top_left_child_shrink); + else if (child == xpaned->top_right_child) + g_value_set_boolean (value, xpaned->top_right_child_shrink); + else if (child == xpaned->bottom_left_child) + g_value_set_boolean (value, xpaned->bottom_left_child_shrink); + else if (child == xpaned->bottom_right_child) + g_value_set_boolean (value, xpaned->bottom_right_child_shrink); + break; + + default: + GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, + property_id, + pspec); + break; + } +} + +static void gtk_xpaned_finalize (GObject* object) +{ + GtkXPaned* xpaned = GTK_XPANED (object); + + gtk_xpaned_set_saved_focus (xpaned, NULL); + gtk_xpaned_set_first_xpaned (xpaned, NULL); + + g_free (xpaned->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void gtk_xpaned_realize (GtkWidget* widget) +{ + GtkXPaned* xpaned; + GdkWindowAttr attributes_east; + GdkWindowAttr attributes_west; + GdkWindowAttr attributes_north; + GdkWindowAttr attributes_south; + GdkWindowAttr attributes_middle; + gint attributes_mask_east; + gint attributes_mask_west; + gint attributes_mask_north; + gint attributes_mask_south; + gint attributes_mask_middle; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + xpaned = GTK_XPANED (widget); + + widget->window = gtk_widget_get_parent_window (widget); + g_object_ref (widget->window); + + attributes_east.window_type = GDK_WINDOW_CHILD; + attributes_west.window_type = GDK_WINDOW_CHILD; + attributes_north.window_type = GDK_WINDOW_CHILD; + attributes_south.window_type = GDK_WINDOW_CHILD; + attributes_middle.window_type = GDK_WINDOW_CHILD; + + attributes_east.wclass = GDK_INPUT_ONLY; + attributes_west.wclass = GDK_INPUT_ONLY; + attributes_north.wclass = GDK_INPUT_ONLY; + attributes_south.wclass = GDK_INPUT_ONLY; + attributes_middle.wclass = GDK_INPUT_ONLY; + + attributes_east.x = xpaned->handle_pos_east.x; + attributes_east.y = xpaned->handle_pos_east.y; + attributes_east.width = xpaned->handle_pos_east.width; + attributes_east.height = xpaned->handle_pos_east.height; + + attributes_west.x = xpaned->handle_pos_west.x; + attributes_west.y = xpaned->handle_pos_west.y; + attributes_west.width = xpaned->handle_pos_west.width; + attributes_west.height = xpaned->handle_pos_west.height; + + attributes_north.x = xpaned->handle_pos_north.x; + attributes_north.y = xpaned->handle_pos_north.y; + attributes_north.width = xpaned->handle_pos_north.width; + attributes_north.height = xpaned->handle_pos_north.height; + + attributes_south.x = xpaned->handle_pos_south.x; + attributes_south.y = xpaned->handle_pos_south.y; + attributes_south.width = xpaned->handle_pos_south.width; + attributes_south.height = xpaned->handle_pos_south.height; + + attributes_middle.x = xpaned->handle_pos_middle.x; + attributes_middle.y = xpaned->handle_pos_middle.y; + attributes_middle.width = xpaned->handle_pos_middle.width; + attributes_middle.height = xpaned->handle_pos_middle.height; + + attributes_east.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + xpaned->cursor_type_east); + attributes_west.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + xpaned->cursor_type_west); + attributes_north.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + xpaned->cursor_type_north); + attributes_south.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + xpaned->cursor_type_south); + attributes_middle.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + xpaned->cursor_type_middle); + + attributes_east.event_mask = gtk_widget_get_events (widget); + attributes_west.event_mask = gtk_widget_get_events (widget); + attributes_north.event_mask = gtk_widget_get_events (widget); + attributes_south.event_mask = gtk_widget_get_events (widget); + attributes_middle.event_mask = gtk_widget_get_events (widget); + + attributes_east.event_mask |= (GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + attributes_west.event_mask |= (GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + attributes_north.event_mask |= (GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + attributes_south.event_mask |= (GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + attributes_middle.event_mask |= (GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + + attributes_mask_east = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR; + attributes_mask_west = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR; + attributes_mask_north = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR; + attributes_mask_south = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR; + attributes_mask_middle = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR; + + xpaned->handle_east = gdk_window_new (widget->window, + &attributes_east, + attributes_mask_east); + xpaned->handle_west = gdk_window_new (widget->window, + &attributes_west, + attributes_mask_west); + xpaned->handle_north = gdk_window_new (widget->window, + &attributes_north, + attributes_mask_north); + xpaned->handle_south = gdk_window_new (widget->window, + &attributes_south, + attributes_mask_south); + xpaned->handle_middle = gdk_window_new (widget->window, + &attributes_middle, + attributes_mask_middle); + + gdk_window_set_user_data (xpaned->handle_east, xpaned); + gdk_window_set_user_data (xpaned->handle_west, xpaned); + gdk_window_set_user_data (xpaned->handle_north, xpaned); + gdk_window_set_user_data (xpaned->handle_south, xpaned); + gdk_window_set_user_data (xpaned->handle_middle, xpaned); + + gdk_cursor_unref (attributes_east.cursor); + gdk_cursor_unref (attributes_west.cursor); + gdk_cursor_unref (attributes_north.cursor); + gdk_cursor_unref (attributes_south.cursor); + gdk_cursor_unref (attributes_middle.cursor); + + widget->style = gtk_style_attach (widget->style, widget->window); + + if (xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) && + xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) && + xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) && + xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child)) + { + gdk_window_show (xpaned->handle_east); + gdk_window_show (xpaned->handle_west); + gdk_window_show (xpaned->handle_north); + gdk_window_show (xpaned->handle_south); + gdk_window_show (xpaned->handle_middle); + } +} + +static void gtk_xpaned_unrealize (GtkWidget *widget) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + if (xpaned->xor_gc) + { + g_object_unref (xpaned->xor_gc); + xpaned->xor_gc = NULL; + } + + if (xpaned->handle_east) + { + gdk_window_set_user_data (xpaned->handle_east, NULL); + gdk_window_destroy (xpaned->handle_east); + xpaned->handle_east = NULL; + } + + if (xpaned->handle_west) + { + gdk_window_set_user_data (xpaned->handle_west, NULL); + gdk_window_destroy (xpaned->handle_west); + xpaned->handle_west = NULL; + } + + if (xpaned->handle_north) + { + gdk_window_set_user_data (xpaned->handle_north, NULL); + gdk_window_destroy (xpaned->handle_north); + xpaned->handle_north = NULL; + } + + if (xpaned->handle_south) + { + gdk_window_set_user_data (xpaned->handle_south, NULL); + gdk_window_destroy (xpaned->handle_south); + xpaned->handle_south = NULL; + } + + if (xpaned->handle_middle) + { + gdk_window_set_user_data (xpaned->handle_middle, NULL); + gdk_window_destroy (xpaned->handle_middle); + xpaned->handle_middle = NULL; + } + + gtk_xpaned_set_last_top_left_child_focus (xpaned, NULL); + gtk_xpaned_set_last_top_right_child_focus (xpaned, NULL); + gtk_xpaned_set_last_bottom_left_child_focus (xpaned, NULL); + gtk_xpaned_set_last_bottom_right_child_focus (xpaned, NULL); + gtk_xpaned_set_saved_focus (xpaned, NULL); + gtk_xpaned_set_first_xpaned (xpaned, NULL); + + if (GTK_WIDGET_CLASS (parent_class)->unrealize) + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); +} + +static void gtk_xpaned_map (GtkWidget* widget) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + gdk_window_show (xpaned->handle_east); + gdk_window_show (xpaned->handle_west); + gdk_window_show (xpaned->handle_north); + gdk_window_show (xpaned->handle_south); + gdk_window_show (xpaned->handle_middle); + + GTK_WIDGET_CLASS (parent_class)->map (widget); +} + +static void gtk_xpaned_unmap (GtkWidget* widget) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + gdk_window_hide (xpaned->handle_east); + gdk_window_hide (xpaned->handle_west); + gdk_window_hide (xpaned->handle_north); + gdk_window_hide (xpaned->handle_south); + gdk_window_hide (xpaned->handle_middle); + + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +static gboolean gtk_xpaned_expose (GtkWidget* widget, + GdkEventExpose* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + gint handle_size; + GdkRectangle horizontalClipArea; + GdkRectangle verticalClipArea; + + /* determine size of handle(s) */ + gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); + + /* I want the handle-"thickness" to be at least 3 */ + g_assert (handle_size >= 3); + + if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) && + xpaned->top_left_child && GTK_WIDGET_VISIBLE (xpaned->top_left_child) && + xpaned->top_right_child && GTK_WIDGET_VISIBLE (xpaned->top_right_child) && + xpaned->bottom_left_child && GTK_WIDGET_VISIBLE (xpaned->bottom_left_child) && + xpaned->bottom_right_child && GTK_WIDGET_VISIBLE (xpaned->bottom_right_child)) + { + GtkStateType state; + + if (gtk_widget_is_focus (widget)) + state = GTK_STATE_SELECTED; + else if (xpaned->handle_prelit) + state = GTK_STATE_PRELIGHT; + else + state = GTK_WIDGET_STATE (widget); + + horizontalClipArea.x = xpaned->handle_pos_west.x; + horizontalClipArea.y = xpaned->handle_pos_west.y; + horizontalClipArea.width = xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width; + horizontalClipArea.height = handle_size; + + verticalClipArea.x = xpaned->handle_pos_north.x; + verticalClipArea.y = xpaned->handle_pos_north.y; + verticalClipArea.width = handle_size; + verticalClipArea.height = xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height; + + gtk_paint_handle (widget->style, + widget->window, + state, + GTK_SHADOW_NONE, + &horizontalClipArea, + widget, + "paned", + xpaned->handle_pos_east.x - handle_size - 256 / 2, + xpaned->handle_pos_west.y + 1, + 256 + handle_size, + handle_size - 2, + /*xpaned->handle_pos_west.x, + xpaned->handle_pos_west.y + 1, + xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width, + handle_size - 2,*/ + GTK_ORIENTATION_HORIZONTAL); + gtk_paint_handle (widget->style, + widget->window, + state, + GTK_SHADOW_NONE, + &verticalClipArea, + widget, + "paned", + xpaned->handle_pos_north.x + 1, + xpaned->handle_pos_south.y - handle_size - 256 / 2, + handle_size - 2, + 256 + handle_size, + /*xpaned->handle_pos_north.x + 1, + xpaned->handle_pos_north.y, + handle_size - 2, + xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height,*/ + GTK_ORIENTATION_VERTICAL); + } + + /* Chain up to draw children */ + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + + return FALSE; +} + +static gboolean is_rtl (GtkXPaned* xpaned) +{ + if (gtk_widget_get_direction (GTK_WIDGET (xpaned)) == GTK_TEXT_DIR_RTL) + return TRUE; + + return FALSE; +} + +static void update_drag (GtkXPaned* xpaned) +{ + GdkPoint pos; + gint handle_size; + GtkRequisition size; + + gtk_widget_get_pointer (GTK_WIDGET (xpaned), &pos.x, &pos.y); + + if (xpaned->in_drag_vert) + { + pos.y -= xpaned->drag_pos.y; + + if (is_rtl (xpaned)) + { + gtk_widget_style_get (GTK_WIDGET (xpaned), + "handle-size", &handle_size, + NULL); + + size.height = GTK_WIDGET (xpaned)->allocation.height - pos.y - handle_size; + } + else + { + size.height = pos.y; + } + + size.height -= GTK_CONTAINER (xpaned)->border_width; + + size.height = CLAMP (size.height, xpaned->min_position.y, xpaned->max_position.y); + + if (size.height != xpaned->top_left_child_size.height) + gtk_xpaned_set_position_y (xpaned, size.height); + } + + if (xpaned->in_drag_horiz) + { + pos.x -= xpaned->drag_pos.x; + + if (is_rtl (xpaned)) + { + gtk_widget_style_get (GTK_WIDGET (xpaned), + "handle-size", &handle_size, + NULL); + + size.width = GTK_WIDGET (xpaned)->allocation.width - pos.x - handle_size; + } + else + { + size.width = pos.x; + } + + size.width -= GTK_CONTAINER (xpaned)->border_width; + + size.width = CLAMP (size.width, xpaned->min_position.x, xpaned->max_position.x); + + if (size.width != xpaned->top_left_child_size.width) + gtk_xpaned_set_position_x (xpaned, size.width); + } + + if (xpaned->in_drag_vert_and_horiz) + { + pos.x -= xpaned->drag_pos.x; + pos.y -= xpaned->drag_pos.y; + + if (is_rtl (xpaned)) + { + gtk_widget_style_get (GTK_WIDGET (xpaned), + "handle-size", &handle_size, + NULL); + + size.width = GTK_WIDGET (xpaned)->allocation.width - pos.x - handle_size; + size.height = GTK_WIDGET (xpaned)->allocation.height - pos.y - handle_size; + } + else + { + size.width = pos.x; + size.height = pos.y; + } + + size.width -= GTK_CONTAINER (xpaned)->border_width; + size.height -= GTK_CONTAINER (xpaned)->border_width; + + size.width = CLAMP (size.width, xpaned->min_position.x, xpaned->max_position.x); + size.height = CLAMP (size.height, xpaned->min_position.y, xpaned->max_position.y); + + if (size.width != xpaned->top_left_child_size.width) + gtk_xpaned_set_position_x (xpaned, size.width); + + if (size.height != xpaned->top_left_child_size.height) + gtk_xpaned_set_position_y (xpaned, size.height); + } +} + +static gboolean gtk_xpaned_enter (GtkWidget* widget, GdkEventCrossing* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + if (xpaned->in_drag_vert || + xpaned->in_drag_horiz || + xpaned->in_drag_vert_and_horiz) + update_drag (xpaned); + else + { + xpaned->handle_prelit = TRUE; + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_east.x, + xpaned->handle_pos_east.y, + xpaned->handle_pos_east.width, + xpaned->handle_pos_east.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_west.x, + xpaned->handle_pos_west.y, + xpaned->handle_pos_west.width, + xpaned->handle_pos_west.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_north.x, + xpaned->handle_pos_north.y, + xpaned->handle_pos_north.width, + xpaned->handle_pos_north.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_south.x, + xpaned->handle_pos_south.y, + xpaned->handle_pos_south.width, + xpaned->handle_pos_south.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_middle.x, + xpaned->handle_pos_middle.y, + xpaned->handle_pos_middle.width, + xpaned->handle_pos_middle.height); + } + + return TRUE; +} + +static gboolean gtk_xpaned_leave (GtkWidget* widget, GdkEventCrossing* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + if (xpaned->in_drag_vert || + xpaned->in_drag_horiz || + xpaned->in_drag_vert_and_horiz) + update_drag (xpaned); + else + { + xpaned->handle_prelit = FALSE; + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_east.x, + xpaned->handle_pos_east.y, + xpaned->handle_pos_east.width, + xpaned->handle_pos_east.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_west.x, + xpaned->handle_pos_west.y, + xpaned->handle_pos_west.width, + xpaned->handle_pos_west.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_north.x, + xpaned->handle_pos_north.y, + xpaned->handle_pos_north.width, + xpaned->handle_pos_north.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_south.x, + xpaned->handle_pos_south.y, + xpaned->handle_pos_south.width, + xpaned->handle_pos_south.height); + + gtk_widget_queue_draw_area (widget, + xpaned->handle_pos_middle.x, + xpaned->handle_pos_middle.y, + xpaned->handle_pos_middle.width, + xpaned->handle_pos_middle.height); + } + + return TRUE; +} + +static gboolean gtk_xpaned_focus (GtkWidget* widget, GtkDirectionType direction) +{ + gboolean retval; + + /* This is a hack, but how can this be done without + * excessive cut-and-paste from gtkcontainer.c? + */ + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS); + retval = (* GTK_WIDGET_CLASS (parent_class)->focus) (widget, direction); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + + return retval; +} + +static gboolean gtk_xpaned_button_press (GtkWidget* widget, + GdkEventButton* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + /* if any child is currently maximized, jump right back */ + if (xpaned->maximized[GTK_XPANED_TOP_LEFT] || + xpaned->maximized[GTK_XPANED_TOP_RIGHT] || + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] || + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + return FALSE; + + /* if user is dragging the handles around */ + if (!xpaned->in_drag_vert_and_horiz && + event->window != xpaned->handle_east && + event->window != xpaned->handle_west && + event->window != xpaned->handle_north && + event->window != xpaned->handle_south && + event->window == xpaned->handle_middle && + event->button == 1) + { + xpaned->in_drag_vert_and_horiz = TRUE; + + /* We need a server grab here, not gtk_grab_add(), since + * we don't want to pass events on to the widget's children */ + if (gdk_pointer_grab (xpaned->handle_middle, + FALSE, + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON1_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK, + NULL, + NULL, + event->time) == GDK_GRAB_SUCCESS) + { + } + + xpaned->drag_pos.x = event->x; + xpaned->drag_pos.y = event->y; + + return TRUE; + } + else if (!xpaned->in_drag_vert && + event->window == xpaned->handle_east && + event->window != xpaned->handle_west && + event->window != xpaned->handle_north && + event->window != xpaned->handle_south && + event->window != xpaned->handle_middle && + event->button == 1) + { + xpaned->in_drag_vert = TRUE; + + /* We need a server grab here, not gtk_grab_add(), since + * we don't want to pass events on to the widget's children */ + if (gdk_pointer_grab (xpaned->handle_east, + FALSE, + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON1_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK, + NULL, + NULL, + event->time) == GDK_GRAB_SUCCESS) + { + } + + xpaned->drag_pos.y = event->y; + + return TRUE; + } + else if (!xpaned->in_drag_vert && + event->window != xpaned->handle_east && + event->window == xpaned->handle_west && + event->window != xpaned->handle_north && + event->window != xpaned->handle_south && + event->window != xpaned->handle_middle && + event->button == 1) + { + xpaned->in_drag_vert = TRUE; + + /* We need a server grab here, not gtk_grab_add(), since + * we don't want to pass events on to the widget's children */ + if (gdk_pointer_grab (xpaned->handle_west, + FALSE, + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON1_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK, + NULL, + NULL, + event->time) == GDK_GRAB_SUCCESS) + { + } + + xpaned->drag_pos.y = event->y; + + return TRUE; + } + else if (!xpaned->in_drag_horiz && + event->window != xpaned->handle_east && + event->window != xpaned->handle_west && + event->window == xpaned->handle_north && + event->window != xpaned->handle_south && + event->window != xpaned->handle_middle && + event->button == 1) + { + xpaned->in_drag_horiz = TRUE; + + /* We need a server grab here, not gtk_grab_add(), since + * we don't want to pass events on to the widget's children */ + if (gdk_pointer_grab (xpaned->handle_north, + FALSE, + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON1_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK, + NULL, + NULL, + event->time) == GDK_GRAB_SUCCESS) + { + } + + xpaned->drag_pos.x = event->x; + + return TRUE; + } + else if (!xpaned->in_drag_horiz && + event->window != xpaned->handle_east && + event->window != xpaned->handle_west && + event->window != xpaned->handle_north && + event->window == xpaned->handle_south && + event->window != xpaned->handle_middle && + event->button == 1) + { + xpaned->in_drag_horiz = TRUE; + + /* We need a server grab here, not gtk_grab_add(), since + * we don't want to pass events on to the widget's children */ + if (gdk_pointer_grab (xpaned->handle_south, + FALSE, + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON1_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK, + NULL, + NULL, + event->time) == GDK_GRAB_SUCCESS) + { + } + + xpaned->drag_pos.x = event->x; + + return TRUE; + } + return FALSE; +} + +static gboolean gtk_xpaned_button_release (GtkWidget* widget, + GdkEventButton* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + if (xpaned->in_drag_vert && (event->button == 1)) + { + xpaned->in_drag_vert = FALSE; + xpaned->drag_pos.y = -1; + xpaned->position_set = TRUE; + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), + event->time); + return TRUE; + } + else if (xpaned->in_drag_horiz && (event->button == 1)) + { + xpaned->in_drag_horiz = FALSE; + xpaned->drag_pos.x = -1; + xpaned->position_set = TRUE; + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), + event->time); + return TRUE; + } + else if (xpaned->in_drag_vert_and_horiz && (event->button == 1)) + { + xpaned->in_drag_vert_and_horiz = FALSE; + xpaned->drag_pos.x = -1; + xpaned->drag_pos.y = -1; + xpaned->position_set = TRUE; + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), + event->time); + return TRUE; + } + + return FALSE; +} + +static gboolean gtk_xpaned_motion (GtkWidget* widget, GdkEventMotion* event) +{ + GtkXPaned* xpaned = GTK_XPANED (widget); + + if (xpaned->in_drag_vert || + xpaned->in_drag_horiz || + xpaned->in_drag_vert_and_horiz) + + { + update_drag (xpaned); + return TRUE; + } + + return FALSE; +} + +void gtk_xpaned_add_top_left (GtkXPaned* xpaned, GtkWidget *widget) +{ + gtk_xpaned_pack_top_left (xpaned, widget, FALSE, TRUE); +} + +void gtk_xpaned_add_top_right (GtkXPaned* xpaned, GtkWidget *widget) +{ + gtk_xpaned_pack_top_right (xpaned, widget, FALSE, TRUE); +} + +void gtk_xpaned_add_bottom_left (GtkXPaned* xpaned, GtkWidget *widget) +{ + gtk_xpaned_pack_bottom_left (xpaned, widget, FALSE, TRUE); +} + +void gtk_xpaned_add_bottom_right (GtkXPaned* xpaned, GtkWidget *widget) +{ + gtk_xpaned_pack_bottom_right (xpaned, widget, FALSE, TRUE); +} + +void gtk_xpaned_pack_top_left (GtkXPaned* xpaned, + GtkWidget* child, + gboolean resize, + gboolean shrink) +{ + g_return_if_fail (GTK_IS_XPANED (xpaned)); + g_return_if_fail (GTK_IS_WIDGET (child)); + + if (!xpaned->top_left_child) + { + xpaned->top_left_child = child; + xpaned->top_left_child_resize = resize; + xpaned->top_left_child_shrink = shrink; + + gtk_widget_set_parent (child, GTK_WIDGET (xpaned)); + } +} + +void gtk_xpaned_pack_top_right (GtkXPaned* xpaned, + GtkWidget* child, + gboolean resize, + gboolean shrink) +{ + g_return_if_fail (GTK_IS_XPANED (xpaned)); + g_return_if_fail (GTK_IS_WIDGET (child)); + + if (!xpaned->top_right_child) + { + xpaned->top_right_child = child; + xpaned->top_right_child_resize = resize; + xpaned->top_right_child_shrink = shrink; + + gtk_widget_set_parent (child, GTK_WIDGET (xpaned)); + } +} + +void gtk_xpaned_pack_bottom_left (GtkXPaned* xpaned, + GtkWidget* child, + gboolean resize, + gboolean shrink) +{ + g_return_if_fail (GTK_IS_XPANED (xpaned)); + g_return_if_fail (GTK_IS_WIDGET (child)); + + if (!xpaned->bottom_left_child) + { + xpaned->bottom_left_child = child; + xpaned->bottom_left_child_resize = resize; + xpaned->bottom_left_child_shrink = shrink; + + gtk_widget_set_parent (child, GTK_WIDGET (xpaned)); + } +} + +void gtk_xpaned_pack_bottom_right (GtkXPaned* xpaned, + GtkWidget* child, + gboolean resize, + gboolean shrink) +{ + g_return_if_fail (GTK_IS_XPANED (xpaned)); + g_return_if_fail (GTK_IS_WIDGET (child)); + + if (!xpaned->bottom_right_child) + { + xpaned->bottom_right_child = child; + xpaned->bottom_right_child_resize = resize; + xpaned->bottom_right_child_shrink = shrink; + + gtk_widget_set_parent (child, GTK_WIDGET (xpaned)); + } +} + +static void gtk_xpaned_add (GtkContainer* container, GtkWidget* widget) +{ + GtkXPaned* xpaned; + + g_return_if_fail (GTK_IS_XPANED (container)); + + xpaned = GTK_XPANED (container); + + if (!xpaned->top_left_child) + gtk_xpaned_add_top_left (xpaned, widget); + else if (!xpaned->top_right_child) + gtk_xpaned_add_top_right (xpaned, widget); + else if (!xpaned->bottom_left_child) + gtk_xpaned_add_bottom_left (xpaned, widget); + else if (!xpaned->bottom_right_child) + gtk_xpaned_add_bottom_right (xpaned, widget); + else + g_warning ("GtkXPaned cannot have more than 4 children\n"); +} + +static void gtk_xpaned_remove (GtkContainer* container, GtkWidget* widget) +{ + GtkXPaned* xpaned; + gboolean was_visible; + + xpaned = GTK_XPANED (container); + was_visible = GTK_WIDGET_VISIBLE (widget); + + if (xpaned->top_left_child == widget) + { + gtk_widget_unparent (widget); + + xpaned->top_left_child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } + else if (xpaned->top_right_child == widget) + { + gtk_widget_unparent (widget); + + xpaned->top_right_child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } + else if (xpaned->bottom_left_child == widget) + { + gtk_widget_unparent (widget); + + xpaned->bottom_left_child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } + else if (xpaned->bottom_right_child == widget) + { + gtk_widget_unparent (widget); + + xpaned->bottom_right_child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } + else + g_warning ("GtkXPaned has no more children attached\n"); + +} + +static void gtk_xpaned_forall (GtkContainer* container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkXPaned* xpaned; + + g_return_if_fail (callback != NULL); + + xpaned = GTK_XPANED (container); + + if (xpaned->top_left_child) + (*callback) (xpaned->top_left_child, callback_data); + if (xpaned->top_right_child) + (*callback) (xpaned->top_right_child, callback_data); + if (xpaned->bottom_left_child) + (*callback) (xpaned->bottom_left_child, callback_data); + if (xpaned->bottom_right_child) + (*callback) (xpaned->bottom_right_child, callback_data); +} + +/** + * gtk_xpaned_get_position_x: + * @paned: a #GtkXPaned widget + * + * Obtains the x-position of the divider. + * + * Return value: x-position of the divider + **/ +gint gtk_xpaned_get_position_x (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), 0); + + return xpaned->top_left_child_size.width; +} + +/** + * gtk_xpaned_get_position_y: + * @paned: a #GtkXPaned widget + * + * Obtains the y-position of the divider. + * + * Return value: y-position of the divider + **/ +gint gtk_xpaned_get_position_y (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), 0); + + return xpaned->top_left_child_size.height; +} + +/** + * gtk_xpaned_set_position_x: + * @paned: a #GtkXPaned widget + * @xposition: pixel x-position of divider, a negative values + * of a component mean that the position is unset. + * + * Sets the x-position of the divider between the four panes. + **/ +void gtk_xpaned_set_position_x (GtkXPaned* xpaned, gint xposition) +{ + GObject* object; + + g_return_if_fail (GTK_IS_XPANED (xpaned)); + + /* if any child is currently maximized, jump right back */ + if (xpaned->maximized[GTK_XPANED_TOP_LEFT] || + xpaned->maximized[GTK_XPANED_TOP_RIGHT] || + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] || + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + return; + + object = G_OBJECT (xpaned); + + if (xposition >= 0) + { + /* We don't clamp here - the assumption is that + * if the total allocation changes at the same time + * as the position, the position set is with reference + * to the new total size. If only the position changes, + * then clamping will occur in gtk_paned_compute_position() + */ + + xpaned->top_left_child_size.width = xposition; + xpaned->position_set = TRUE; + } + else + { + xpaned->position_set = FALSE; + } + + g_object_freeze_notify (object); + g_object_notify (object, "x-position"); + g_object_notify (object, "position-set"); + g_object_thaw_notify (object); + + gtk_widget_queue_resize (GTK_WIDGET (xpaned)); +} + +/** + * gtk_xpaned_set_position_y: + * @paned: a #GtkXPaned widget + * @yposition: pixel y-position of divider, a negative values + * of a component mean that the position is unset. + * + * Sets the y-position of the divider between the four panes. + **/ +void gtk_xpaned_set_position_y (GtkXPaned* xpaned, gint yposition) +{ + GObject* object; + + g_return_if_fail (GTK_IS_XPANED (xpaned)); + + /* if any child is currently maximized, jump right back */ + if (xpaned->maximized[GTK_XPANED_TOP_LEFT] || + xpaned->maximized[GTK_XPANED_TOP_RIGHT] || + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] || + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + return; + + object = G_OBJECT (xpaned); + + if (yposition >= 0) + { + /* We don't clamp here - the assumption is that + * if the total allocation changes at the same time + * as the position, the position set is with reference + * to the new total size. If only the position changes, + * then clamping will occur in gtk_paned_compute_position() + */ + + xpaned->top_left_child_size.height = yposition; + xpaned->position_set = TRUE; + } + else + { + xpaned->position_set = FALSE; + } + + g_object_freeze_notify (object); + g_object_notify (object, "y-position"); + g_object_notify (object, "position-set"); + g_object_thaw_notify (object); + + gtk_widget_queue_resize (GTK_WIDGET (xpaned)); +} + +/* this call is private and only intended for internal use! */ +void gtk_xpaned_save_unmaximized_x (GtkXPaned* xpaned) +{ + xpaned->unmaximized_position.x = gtk_xpaned_get_position_x (xpaned); +} + +/* this call is private and only intended for internal use! */ +void gtk_xpaned_save_unmaximized_y (GtkXPaned* xpaned) +{ + xpaned->unmaximized_position.y = gtk_xpaned_get_position_y (xpaned); +} + +/* this call is private and only intended for internal use! */ +gint gtk_xpaned_fetch_unmaximized_x (GtkXPaned* xpaned) +{ + return xpaned->unmaximized_position.x; +} + +/* this call is private and only intended for internal use! */ +gint gtk_xpaned_fetch_unmaximized_y (GtkXPaned* xpaned) +{ + return xpaned->unmaximized_position.y; +} + +/** + * gtk_xpaned_get_top_left_child: + * @xpaned: a #GtkXPaned widget + * + * Obtains the top-left child of the xpaned widget. + * + * Return value: top-left child, or %NULL if it is not set. + * + * Since: 2.4 + **/ +GtkWidget* gtk_xpaned_get_top_left_child (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL); + + return xpaned->top_left_child; +} + +/** + * gtk_xpaned_get_top_right_child: + * @xpaned: a #GtkXPaned widget + * + * Obtains the top-right child of the xpaned widget. + * + * Return value: top-right child, or %NULL if it is not set. + * + * Since: 2.4 + **/ +GtkWidget* gtk_xpaned_get_top_right_child (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL); + + return xpaned->top_right_child; +} + +/** + * gtk_xpaned_get_bottom_left_child: + * @xpaned: a #GtkXPaned widget + * + * Obtains the bottom-left child of the xpaned widget. + * + * Return value: bottom-left child, or %NULL if it is not set. + * + * Since: 2.4 + **/ +GtkWidget* gtk_xpaned_get_bottom_left_child (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL); + + return xpaned->bottom_left_child; +} + +/** + * gtk_xpaned_get_bottom_right_child: + * @xpaned: a #GtkXPaned widget + * + * Obtains the bottom-right child of the xpaned widget. + * + * Return value: bottom-right child, or %NULL if it is not set. + * + * Since: 2.4 + **/ +GtkWidget* gtk_xpaned_get_bottom_right_child (GtkXPaned* xpaned) +{ + g_return_val_if_fail (GTK_IS_XPANED (xpaned), NULL); + + return xpaned->bottom_right_child; +} + +gboolean gtk_xpaned_maximize_top_left (GtkXPaned* xpaned, gboolean maximize) +{ + if (maximize) + { + /* see if any child is already maximized */ + if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] && + !xpaned->maximized[GTK_XPANED_TOP_RIGHT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + { + /* save current position */ + gtk_xpaned_save_unmaximized_x (xpaned); + gtk_xpaned_save_unmaximized_y (xpaned); + + /* set new maximized position */ + gtk_xpaned_set_position_x (xpaned, xpaned->max_position.x); + gtk_xpaned_set_position_y (xpaned, xpaned->max_position.y); + + /* mark maximized flag for top-left child */ + xpaned->maximized[GTK_XPANED_TOP_LEFT] = TRUE; + + return TRUE; + } + /* already one child maximized, report error */ + else + return FALSE; + } + else + { + /* verify that top-left child is really currently maximized */ + if (xpaned->maximized[GTK_XPANED_TOP_LEFT]) + { + /* clear maximized flat for top-left child */ + xpaned->maximized[GTK_XPANED_TOP_LEFT] = FALSE; + + /* restore unmaximized position */ + gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned)); + gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned)); + + return TRUE; + } + /* top-left child is currently not maximized, report error */ + else + return FALSE; + } +} + +gboolean gtk_xpaned_maximize_top_right (GtkXPaned* xpaned, gboolean maximize) +{ + if (maximize) + { + /* see if any child is already maximized */ + if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] && + !xpaned->maximized[GTK_XPANED_TOP_RIGHT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + { + /* save current position */ + gtk_xpaned_save_unmaximized_x (xpaned); + gtk_xpaned_save_unmaximized_y (xpaned); + + /* set new maximized position */ + gtk_xpaned_set_position_x (xpaned, xpaned->min_position.x); + gtk_xpaned_set_position_y (xpaned, xpaned->max_position.y); + + /* mark maximized flag for top-right child */ + xpaned->maximized[GTK_XPANED_TOP_RIGHT] = TRUE; + + return TRUE; + } + /* already one child maximized, report error */ + else + return FALSE; + } + else + { + /* verify that top-right child is really currently maximized */ + if (xpaned->maximized[GTK_XPANED_TOP_RIGHT]) + { + /* clear maximized flat for top-right child */ + xpaned->maximized[GTK_XPANED_TOP_RIGHT] = FALSE; + + /* restore unmaximized position */ + gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned)); + gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned)); + + return TRUE; + } + /* top-right child is currently not maximized, report error */ + else + return FALSE; + } +} + +gboolean gtk_xpaned_maximize_bottom_left (GtkXPaned* xpaned, gboolean maximize) +{ + if (maximize) + { + /* see if any child is already maximized */ + if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] && + !xpaned->maximized[GTK_XPANED_TOP_RIGHT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + { + /* save current position */ + gtk_xpaned_save_unmaximized_x (xpaned); + gtk_xpaned_save_unmaximized_y (xpaned); + + /* set new maximized position */ + gtk_xpaned_set_position_x (xpaned, xpaned->max_position.x); + gtk_xpaned_set_position_y (xpaned, xpaned->min_position.y); + + /* mark maximized flag for bottom-left child */ + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = TRUE; + + return TRUE; + } + /* already one child maximized, report error */ + else + return FALSE; + } + else + { + /* verify that bottom-left child is really currently maximized */ + if (xpaned->maximized[GTK_XPANED_BOTTOM_LEFT]) + { + /* clear maximized flat for bottom-left child */ + xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] = FALSE; + + /* restore unmaximized position */ + gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned)); + gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned)); + + return TRUE; + } + /* bottom-left child is currently not maximized, report error */ + else + return FALSE; + } +} + +gboolean gtk_xpaned_maximize_bottom_right (GtkXPaned* xpaned, gboolean maximize) +{ + if (maximize) + { + /* see if any child is already maximized */ + if (!xpaned->maximized[GTK_XPANED_TOP_LEFT] && + !xpaned->maximized[GTK_XPANED_TOP_RIGHT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_LEFT] && + !xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + { + /* save current position */ + gtk_xpaned_save_unmaximized_x (xpaned); + gtk_xpaned_save_unmaximized_y (xpaned); + + /* set new maximized position */ + gtk_xpaned_set_position_x (xpaned, xpaned->min_position.x); + gtk_xpaned_set_position_y (xpaned, xpaned->min_position.y); + + /* mark maximized flag for bottom-right child */ + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = TRUE; + + return TRUE; + } + /* already one child maximized, report error */ + else + return FALSE; + } + else + { + /* verify that bottom-right child is really currently maximized */ + if (xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT]) + { + /* clear maximized flat for bottom-right child */ + xpaned->maximized[GTK_XPANED_BOTTOM_RIGHT] = FALSE; + + /* restore unmaximized position */ + gtk_xpaned_set_position_x (xpaned, gtk_xpaned_fetch_unmaximized_x (xpaned)); + gtk_xpaned_set_position_y (xpaned, gtk_xpaned_fetch_unmaximized_y (xpaned)); + + return TRUE; + } + /* bottom-right child is currently not maximized, report error */ + else + return FALSE; + } +} + +void +gtk_xpaned_compute_position (GtkXPaned* xpaned, + const GtkAllocation* allocation, + GtkRequisition* top_left_child_req, + GtkRequisition* top_right_child_req, + GtkRequisition* bottom_left_child_req, + GtkRequisition* bottom_right_child_req) +{ + GdkPoint old_position; + GdkPoint old_min_position; + GdkPoint old_max_position; + gint handle_size; + gint border_width = GTK_CONTAINER (xpaned)->border_width; + float fX; + float fY; + + g_return_if_fail (GTK_IS_XPANED (xpaned)); + + old_position.x = xpaned->top_left_child_size.width; + old_position.y = xpaned->top_left_child_size.height; + old_min_position.x = xpaned->min_position.x; + old_min_position.y = xpaned->min_position.y; + old_max_position.x = xpaned->max_position.x; + old_max_position.y = xpaned->max_position.y; + + fX = 100.0f * (float) old_position.x / (float) allocation->width; + fY = 100.0f * (float) old_position.y / (float) allocation->height; + + xpaned->min_position.x = xpaned->top_left_child_shrink ? 0 : top_left_child_req->width; + xpaned->min_position.y = xpaned->top_left_child_shrink ? 0 : top_left_child_req->height; + + gtk_widget_style_get (GTK_WIDGET (xpaned), "handle-size", &handle_size, NULL); + + xpaned->max_position.x = allocation->width - 2 * border_width - handle_size; + xpaned->max_position.y = allocation->height - 2 * border_width - handle_size; + if (!xpaned->top_left_child_shrink) + xpaned->max_position.x = MAX (1, xpaned->max_position.x - top_left_child_req->width); + xpaned->max_position.x = MAX (xpaned->min_position.x, xpaned->max_position.x); + + if (!xpaned->position_set) + { + if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize) + { + xpaned->top_left_child_size.width = MAX (0, allocation->width - top_right_child_req->width); + xpaned->top_left_child_size.height = MAX (0, allocation->height - top_right_child_req->height); + } + else if (!xpaned->top_left_child_resize && xpaned->top_right_child_resize) + { + xpaned->top_left_child_size.width = top_left_child_req->width; + xpaned->top_left_child_size.height = top_left_child_req->height; + } + else if (top_left_child_req->width + top_right_child_req->width != 0) + { + xpaned->top_left_child_size.width = allocation->width * ((gdouble)top_left_child_req->width / (top_left_child_req->width + top_right_child_req->width)) + 0.5; + } + else if (top_left_child_req->height + top_right_child_req->height != 0) + { + xpaned->top_left_child_size.height = allocation->height * ((gdouble)top_left_child_req->height / (top_left_child_req->height + top_right_child_req->height)) + 0.5; + } + else + { + xpaned->top_left_child_size.width = allocation->width * 0.5 + 0.5; + xpaned->top_left_child_size.height = allocation->height * 0.5 + 0.5; + } + } + else + { + /* If the position was set before the initial allocation. + ** (paned->last_allocation <= 0) just clamp it and leave it. */ + if (xpaned->last_allocation.width > 0) + { + if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize) + { + xpaned->top_left_child_size.width += allocation->width + - xpaned->last_allocation.width; + + xpaned->top_left_child_size.height += allocation->height + - xpaned->last_allocation.height; + } + else if (!(!xpaned->top_left_child_resize && xpaned->top_right_child_resize)) + { + xpaned->top_left_child_size.width = allocation->width + * ((gdouble) xpaned->top_left_child_size.width / (xpaned->last_allocation.width)) + + 0.5; + + xpaned->top_left_child_size.height = allocation->height + * ((gdouble) xpaned->top_left_child_size.height / (xpaned->last_allocation.height)) + + 0.5; + } + } + if (xpaned->last_allocation.height > 0) + { + if (xpaned->top_left_child_resize && !xpaned->top_right_child_resize) + { + xpaned->top_left_child_size.width += allocation->width - xpaned->last_allocation.width; + xpaned->top_left_child_size.height += allocation->height - xpaned->last_allocation.height; + } + else if (!(!xpaned->top_left_child_resize && xpaned->top_right_child_resize)) + { + xpaned->top_left_child_size.width = allocation->width * ((gdouble) xpaned->top_left_child_size.width / (xpaned->last_allocation.width)) + 0.5; + xpaned->top_left_child_size.height = allocation->height * ((gdouble) xpaned->top_left_child_size.height / (xpaned->last_allocation.height)) + 0.5; + } + } + + } + + xpaned->top_left_child_size.width = CLAMP (xpaned->top_left_child_size.width, + xpaned->min_position.x, + xpaned->max_position.x); + xpaned->top_left_child_size.height = CLAMP (xpaned->top_left_child_size.height, + xpaned->min_position.y, + xpaned->max_position.y); + + xpaned->top_right_child_size.width = CLAMP (xpaned->top_right_child_size.width, + xpaned->min_position.x, + xpaned->max_position.x); + xpaned->top_right_child_size.height = CLAMP (xpaned->top_right_child_size.height, + xpaned->min_position.y, + xpaned->max_position.y); + + xpaned->bottom_left_child_size.width = CLAMP (xpaned->bottom_left_child_size.width, + xpaned->min_position.x, + xpaned->max_position.x); + xpaned->bottom_left_child_size.height = CLAMP (xpaned->bottom_left_child_size.height, + xpaned->min_position.y, + xpaned->max_position.y); + + xpaned->bottom_right_child_size.width = CLAMP (xpaned->bottom_right_child_size.width, + xpaned->min_position.x, + xpaned->max_position.x); + xpaned->bottom_right_child_size.height = CLAMP (xpaned->bottom_right_child_size.height, + xpaned->min_position.y, + xpaned->max_position.y); + + gtk_widget_set_child_visible (xpaned->top_left_child, TRUE); + gtk_widget_set_child_visible (xpaned->top_right_child, TRUE); + gtk_widget_set_child_visible (xpaned->bottom_left_child, TRUE); + gtk_widget_set_child_visible (xpaned->bottom_right_child, TRUE); + + g_object_freeze_notify (G_OBJECT (xpaned)); + + if (xpaned->top_left_child_size.width != old_position.x) + g_object_notify (G_OBJECT (xpaned), "x-position"); + if (xpaned->top_left_child_size.height != old_position.y) + g_object_notify (G_OBJECT (xpaned), "y-position"); + + if (xpaned->top_right_child_size.width != old_position.x) + g_object_notify (G_OBJECT (xpaned), "x-position"); + if (xpaned->top_right_child_size.height != old_position.y) + g_object_notify (G_OBJECT (xpaned), "y-position"); + + if (xpaned->bottom_left_child_size.width != old_position.x) + g_object_notify (G_OBJECT (xpaned), "x-position"); + if (xpaned->bottom_left_child_size.height != old_position.y) + g_object_notify (G_OBJECT (xpaned), "y-position"); + + if (xpaned->bottom_right_child_size.width != old_position.x) + g_object_notify (G_OBJECT (xpaned), "x-position"); + if (xpaned->bottom_right_child_size.height != old_position.y) + g_object_notify (G_OBJECT (xpaned), "y-position"); + + if (xpaned->min_position.x != old_min_position.x) + g_object_notify (G_OBJECT (xpaned), "min-x-position"); + if (xpaned->min_position.y != old_min_position.y) + g_object_notify (G_OBJECT (xpaned), "min-y-position"); + + if (xpaned->max_position.x != old_max_position.x) + g_object_notify (G_OBJECT (xpaned), "max-y-position"); + if (xpaned->max_position.y != old_max_position.y) + g_object_notify (G_OBJECT (xpaned), "max-y-position"); + + g_object_thaw_notify (G_OBJECT (xpaned)); + + xpaned->last_allocation.width = allocation->width; + xpaned->last_allocation.height = allocation->height; + + fX = 100.0f * (float) old_position.x / (float) allocation->width; + fY = 100.0f * (float) old_position.y / (float) allocation->height; +} + +static void gtk_xpaned_set_saved_focus (GtkXPaned* xpaned, GtkWidget* widget) +{ + if (xpaned->priv->saved_focus) + g_object_remove_weak_pointer (G_OBJECT (xpaned->priv->saved_focus), + (gpointer *)&(xpaned->priv->saved_focus)); + + xpaned->priv->saved_focus = widget; + + if (xpaned->priv->saved_focus) + g_object_add_weak_pointer (G_OBJECT (xpaned->priv->saved_focus), + (gpointer *)&(xpaned->priv->saved_focus)); +} + +static void gtk_xpaned_set_first_xpaned (GtkXPaned* xpaned, + GtkXPaned* first_xpaned) +{ + if (xpaned->priv->first_xpaned) + g_object_remove_weak_pointer (G_OBJECT (xpaned->priv->first_xpaned), + (gpointer *)&(xpaned->priv->first_xpaned)); + + xpaned->priv->first_xpaned = first_xpaned; + + if (xpaned->priv->first_xpaned) + g_object_add_weak_pointer (G_OBJECT (xpaned->priv->first_xpaned), + (gpointer *)&(xpaned->priv->first_xpaned)); +} + +static void gtk_xpaned_set_last_top_left_child_focus (GtkXPaned* xpaned, + GtkWidget* widget) +{ + if (xpaned->last_top_left_child_focus) + g_object_remove_weak_pointer (G_OBJECT (xpaned->last_top_left_child_focus), + (gpointer *)&(xpaned->last_top_left_child_focus)); + + xpaned->last_top_left_child_focus = widget; + + if (xpaned->last_top_left_child_focus) + g_object_add_weak_pointer (G_OBJECT (xpaned->last_top_left_child_focus), + (gpointer *)&(xpaned->last_top_left_child_focus)); +} + +static void gtk_xpaned_set_last_top_right_child_focus (GtkXPaned* xpaned, + GtkWidget *widget) +{ + if (xpaned->last_top_right_child_focus) + g_object_remove_weak_pointer (G_OBJECT (xpaned->last_top_right_child_focus), + (gpointer *)&(xpaned->last_top_right_child_focus)); + + xpaned->last_top_right_child_focus = widget; + + if (xpaned->last_top_right_child_focus) + g_object_add_weak_pointer (G_OBJECT (xpaned->last_top_right_child_focus), + (gpointer *)&(xpaned->last_top_right_child_focus)); +} + +static void gtk_xpaned_set_last_bottom_left_child_focus (GtkXPaned* xpaned, + GtkWidget *widget) +{ + if (xpaned->last_bottom_left_child_focus) + g_object_remove_weak_pointer (G_OBJECT (xpaned->last_bottom_left_child_focus), + (gpointer *)&(xpaned->last_bottom_left_child_focus)); + + xpaned->last_bottom_left_child_focus = widget; + + if (xpaned->last_bottom_left_child_focus) + g_object_add_weak_pointer (G_OBJECT (xpaned->last_bottom_left_child_focus), + (gpointer *)&(xpaned->last_bottom_left_child_focus)); +} + +static void gtk_xpaned_set_last_bottom_right_child_focus (GtkXPaned* xpaned, + GtkWidget *widget) +{ + if (xpaned->last_bottom_right_child_focus) + g_object_remove_weak_pointer (G_OBJECT (xpaned->last_bottom_right_child_focus), + (gpointer *)&(xpaned->last_bottom_right_child_focus)); + + xpaned->last_bottom_right_child_focus = widget; + + if (xpaned->last_bottom_right_child_focus) + g_object_add_weak_pointer (G_OBJECT (xpaned->last_bottom_right_child_focus), + (gpointer *)&(xpaned->last_bottom_right_child_focus)); +} + +static GtkWidget* xpaned_get_focus_widget (GtkXPaned* xpaned) +{ + GtkWidget* toplevel; + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned)); + if (GTK_WIDGET_TOPLEVEL (toplevel)) + return GTK_WINDOW (toplevel)->focus_widget; + + return NULL; +} + +static void gtk_xpaned_set_focus_child (GtkContainer* container, + GtkWidget* focus_child) +{ + GtkXPaned* xpaned; + + g_return_if_fail (GTK_IS_XPANED (container)); + + xpaned = GTK_XPANED (container); + + if (focus_child == NULL) + { + GtkWidget* last_focus; + GtkWidget* w; + + last_focus = xpaned_get_focus_widget (xpaned); + + if (last_focus) + { + /* If there is one or more paned widgets between us and the + * focus widget, we want the topmost of those as last_focus + */ + for (w = last_focus; w != GTK_WIDGET (xpaned); w = w->parent) + if (GTK_IS_XPANED (w)) + last_focus = w; + + if (container->focus_child == xpaned->top_left_child) + gtk_xpaned_set_last_top_left_child_focus (xpaned, last_focus); + else if (container->focus_child == xpaned->top_right_child) + gtk_xpaned_set_last_top_right_child_focus (xpaned, last_focus); + else if (container->focus_child == xpaned->bottom_left_child) + gtk_xpaned_set_last_bottom_left_child_focus (xpaned, last_focus); + else if (container->focus_child == xpaned->bottom_right_child) + gtk_xpaned_set_last_bottom_right_child_focus (xpaned, last_focus); + } + } + + if (parent_class->set_focus_child) + (* parent_class->set_focus_child) (container, focus_child); +} + +static void gtk_xpaned_get_cycle_chain (GtkXPaned* xpaned, + GtkDirectionType direction, + GList** widgets) +{ + GtkContainer* container = GTK_CONTAINER (xpaned); + GtkWidget* ancestor = NULL; + GList* temp_list = NULL; + GList* list; + + if (xpaned->in_recursion) + return; + + g_assert (widgets != NULL); + + if (xpaned->last_top_left_child_focus && + !gtk_widget_is_ancestor (xpaned->last_top_left_child_focus, + GTK_WIDGET (xpaned))) + { + gtk_xpaned_set_last_top_left_child_focus (xpaned, NULL); + } + + if (xpaned->last_top_right_child_focus && + !gtk_widget_is_ancestor (xpaned->last_top_right_child_focus, + GTK_WIDGET (xpaned))) + { + gtk_xpaned_set_last_top_right_child_focus (xpaned, NULL); + } + + if (xpaned->last_bottom_left_child_focus && + !gtk_widget_is_ancestor (xpaned->last_bottom_left_child_focus, + GTK_WIDGET (xpaned))) + { + gtk_xpaned_set_last_bottom_left_child_focus (xpaned, NULL); + } + + if (xpaned->last_bottom_right_child_focus && + !gtk_widget_is_ancestor (xpaned->last_bottom_right_child_focus, + GTK_WIDGET (xpaned))) + { + gtk_xpaned_set_last_bottom_right_child_focus (xpaned, NULL); + } + + if (GTK_WIDGET (xpaned)->parent) + ancestor = gtk_widget_get_ancestor (GTK_WIDGET (xpaned)->parent, + GTK_TYPE_XPANED); + + /* The idea here is that temp_list is a list of widgets we want to cycle + * to. The list is prioritized so that the first element is our first + * choice, the next our second, and so on. + * + * We can't just use g_list_reverse(), because we want to try + * paned->last_child?_focus before paned->child?, both when we + * are going forward and backward. + */ + if (direction == GTK_DIR_TAB_FORWARD) + { + if (container->focus_child == xpaned->top_left_child) + { + temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_right_child); + temp_list = g_list_append (temp_list, ancestor); + } + else if (container->focus_child == xpaned->top_right_child) + { + temp_list = g_list_append (temp_list, ancestor); + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + } + else if (container->focus_child == xpaned->bottom_left_child) + { + temp_list = g_list_append (temp_list, ancestor); + temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_right_child); + } + else if (container->focus_child == xpaned->bottom_right_child) + { + temp_list = g_list_append (temp_list, ancestor); + temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_left_child); + } + else + { + temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_left_child); + temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_right_child); + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_right_child); + temp_list = g_list_append (temp_list, ancestor); + } + } + else + { + if (container->focus_child == xpaned->top_left_child) + { + temp_list = g_list_append (temp_list, ancestor); + temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_right_child); + } + else if (container->focus_child == xpaned->top_right_child) + { + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + temp_list = g_list_append (temp_list, ancestor); + } + else if (container->focus_child == xpaned->bottom_right_child) + { + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + temp_list = g_list_append (temp_list, ancestor); + } + else if (container->focus_child == xpaned->top_right_child) + { + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + temp_list = g_list_append (temp_list, ancestor); + } + else + { + temp_list = g_list_append (temp_list, xpaned->last_bottom_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_right_child); + temp_list = g_list_append (temp_list, xpaned->last_bottom_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->bottom_left_child); + temp_list = g_list_append (temp_list, xpaned->last_top_right_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_right_child); + temp_list = g_list_append (temp_list, xpaned->last_top_left_child_focus); + temp_list = g_list_append (temp_list, xpaned->top_left_child); + temp_list = g_list_append (temp_list, ancestor); + } + } + + /* Walk the list and expand all the paned widgets. */ + for (list = temp_list; list != NULL; list = list->next) + { + GtkWidget *widget = list->data; + + if (widget) + { + if (GTK_IS_XPANED (widget)) + { + xpaned->in_recursion = TRUE; + gtk_xpaned_get_cycle_chain (GTK_XPANED (widget), + direction, + widgets); + xpaned->in_recursion = FALSE; + } + else + { + *widgets = g_list_append (*widgets, widget); + } + } + } + + g_list_free (temp_list); +} + +static gboolean gtk_xpaned_cycle_child_focus (GtkXPaned* xpaned, + gboolean reversed) +{ + GList* cycle_chain = NULL; + GList* list; + + GtkDirectionType direction = reversed ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD; + + /* ignore f6 if the handle is focused */ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + return TRUE; + + /* we can't just let the event propagate up the hierarchy, + * because the paned will want to cycle focus _unless_ an + * ancestor paned handles the event + */ + gtk_xpaned_get_cycle_chain (xpaned, direction, &cycle_chain); + + for (list = cycle_chain; list != NULL; list = list->next) + if (gtk_widget_child_focus (GTK_WIDGET (list->data), direction)) + break; + + g_list_free (cycle_chain); + + return TRUE; +} + +static void get_child_xpanes (GtkWidget* widget, GList** xpanes) +{ + if (GTK_IS_XPANED (widget)) + { + GtkXPaned* xpaned = GTK_XPANED (widget); + + get_child_xpanes (xpaned->top_left_child, xpanes); + *xpanes = g_list_prepend (*xpanes, widget); + get_child_xpanes (xpaned->top_right_child, xpanes); + *xpanes = g_list_prepend (*xpanes, widget); + get_child_xpanes (xpaned->bottom_left_child, xpanes); + *xpanes = g_list_prepend (*xpanes, widget); + get_child_xpanes (xpaned->bottom_right_child, xpanes); + } + else if (GTK_IS_CONTAINER (widget)) + { + gtk_container_foreach (GTK_CONTAINER (widget), + (GtkCallback)get_child_xpanes, + xpanes); + } +} + +static GList* get_all_xpanes (GtkXPaned* xpaned) +{ + GtkXPaned* topmost = NULL; + GList* result = NULL; + GtkWidget* w; + + for (w = GTK_WIDGET (xpaned); w != NULL; w = w->parent) + { + if (GTK_IS_XPANED (w)) + topmost = GTK_XPANED (w); + } + + g_assert (topmost); + + get_child_xpanes (GTK_WIDGET (topmost), &result); + + return g_list_reverse (result); +} + +static void gtk_xpaned_find_neighbours (GtkXPaned* xpaned, + GtkXPaned** next, + GtkXPaned** prev) +{ + GList* all_xpanes; + GList* this_link; + + all_xpanes = get_all_xpanes (xpaned); + g_assert (all_xpanes); + + this_link = g_list_find (all_xpanes, xpaned); + + g_assert (this_link); + + if (this_link->next) + *next = this_link->next->data; + else + *next = all_xpanes->data; + + if (this_link->prev) + *prev = this_link->prev->data; + else + *prev = g_list_last (all_xpanes)->data; + + g_list_free (all_xpanes); +} + +static gboolean gtk_xpaned_move_handle (GtkXPaned* xpaned, GtkScrollType scroll) +{ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + GdkPoint old_position; + GdkPoint new_position; + gint increment; + + enum + { + SINGLE_STEP_SIZE = 1, + PAGE_STEP_SIZE = 75 + }; + + new_position.x = old_position.x = gtk_xpaned_get_position_x (xpaned); + new_position.y = old_position.y = gtk_xpaned_get_position_y (xpaned); + increment = 0; + + switch (scroll) + { + case GTK_SCROLL_STEP_LEFT: + case GTK_SCROLL_STEP_UP: + case GTK_SCROLL_STEP_BACKWARD: + increment = - SINGLE_STEP_SIZE; + break; + + case GTK_SCROLL_STEP_RIGHT: + case GTK_SCROLL_STEP_DOWN: + case GTK_SCROLL_STEP_FORWARD: + increment = SINGLE_STEP_SIZE; + break; + + case GTK_SCROLL_PAGE_LEFT: + case GTK_SCROLL_PAGE_UP: + case GTK_SCROLL_PAGE_BACKWARD: + increment = - PAGE_STEP_SIZE; + break; + + case GTK_SCROLL_PAGE_RIGHT: + case GTK_SCROLL_PAGE_DOWN: + case GTK_SCROLL_PAGE_FORWARD: + increment = PAGE_STEP_SIZE; + break; + + case GTK_SCROLL_START: + new_position.x = xpaned->min_position.x; + new_position.y = xpaned->min_position.y; + break; + + case GTK_SCROLL_END: + new_position.x = xpaned->max_position.x; + new_position.y = xpaned->max_position.y; + break; + + default: + break; + } + + if (increment) + { + if (is_rtl (xpaned)) + increment = -increment; + + new_position.x = old_position.x + increment; + new_position.y = old_position.y + increment; + } + + new_position.x = CLAMP (new_position.x, + xpaned->min_position.x, + xpaned->max_position.x); + + new_position.y = CLAMP (new_position.y, + xpaned->min_position.y, + xpaned->max_position.y); + + if (old_position.x != new_position.x) + gtk_xpaned_set_position_x (xpaned, new_position.x); + + if (old_position.y != new_position.y) + gtk_xpaned_set_position_y (xpaned, new_position.y); + + return TRUE; + } + + return FALSE; +} + +static void gtk_xpaned_restore_focus (GtkXPaned* xpaned) +{ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + if (xpaned->priv->saved_focus && + GTK_WIDGET_SENSITIVE (xpaned->priv->saved_focus)) + { + gtk_widget_grab_focus (xpaned->priv->saved_focus); + } + else + { + /* the saved focus is somehow not available for focusing, + * try + * 1) tabbing into the paned widget + * if that didn't work, + * 2) unset focus for the window if there is one + */ + + if (!gtk_widget_child_focus (GTK_WIDGET (xpaned), GTK_DIR_TAB_FORWARD)) + { + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned)); + + if (GTK_IS_WINDOW (toplevel)) + gtk_window_set_focus (GTK_WINDOW (toplevel), NULL); + } + } + + gtk_xpaned_set_saved_focus (xpaned, NULL); + gtk_xpaned_set_first_xpaned (xpaned, NULL); + } +} + +static gboolean gtk_xpaned_accept_position (GtkXPaned* xpaned) +{ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + xpaned->original_position.x = -1; + xpaned->original_position.y = -1; + gtk_xpaned_restore_focus (xpaned); + + return TRUE; + } + + return FALSE; +} + +static gboolean gtk_xpaned_cancel_position (GtkXPaned* xpaned) +{ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + if (xpaned->original_position.x != -1) + { + gtk_xpaned_set_position_x (xpaned, xpaned->original_position.x); + xpaned->original_position.x = -1; + } + + if (xpaned->original_position.y != -1) + { + gtk_xpaned_set_position_y (xpaned, xpaned->original_position.y); + xpaned->original_position.y = -1; + } + + gtk_xpaned_restore_focus (xpaned); + return TRUE; + } + + return FALSE; +} + +static gboolean gtk_xpaned_cycle_handle_focus (GtkXPaned* xpaned, + gboolean reversed) +{ + GtkXPaned* next; + GtkXPaned* prev; + + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + GtkXPaned* focus = NULL; + + if (!xpaned->priv->first_xpaned) + { + /* The first_pane has disappeared. As an ad-hoc solution, + * we make the currently focused paned the first_paned. To the + * user this will seem like the paned cycling has been reset. + */ + gtk_xpaned_set_first_xpaned (xpaned, xpaned); + } + + gtk_xpaned_find_neighbours (xpaned, &next, &prev); + + if (reversed && prev && + prev != xpaned && xpaned != xpaned->priv->first_xpaned) + { + focus = prev; + } + else if (!reversed && + next && + next != xpaned && + next != xpaned->priv->first_xpaned) + { + focus = next; + } + else + { + gtk_xpaned_accept_position (xpaned); + return TRUE; + } + + g_assert (focus); + + gtk_xpaned_set_saved_focus (focus, xpaned->priv->saved_focus); + gtk_xpaned_set_first_xpaned (focus, xpaned->priv->first_xpaned); + + gtk_xpaned_set_saved_focus (xpaned, NULL); + gtk_xpaned_set_first_xpaned (xpaned, NULL); + + gtk_widget_grab_focus (GTK_WIDGET (focus)); + + if (!gtk_widget_is_focus (GTK_WIDGET (xpaned))) + { + xpaned->original_position.x = -1; + xpaned->original_position.y = -1; + focus->original_position.x = gtk_xpaned_get_position_x (focus); + focus->original_position.y = gtk_xpaned_get_position_y (focus); + } + } + else + { + GtkContainer* container = GTK_CONTAINER (xpaned); + GtkXPaned* focus; + GtkXPaned* first; + GtkXPaned* prev; + GtkXPaned* next; + GtkWidget* toplevel; + + gtk_xpaned_find_neighbours (xpaned, &next, &prev); + + if (container->focus_child == xpaned->top_left_child) + { + if (reversed) + { + focus = prev; + first = xpaned; + } + else + { + focus = xpaned; + first = xpaned; + } + } + else if (container->focus_child == xpaned->top_right_child) + { + if (reversed) + { + focus = xpaned; + first = next; + } + else + { + focus = next; + first = next; + } + } + else + { + /* Focus is not inside this xpaned, and we don't have focus. + * Presumably this happened because the application wants us + * to start keyboard navigating. + */ + focus = xpaned; + + if (reversed) + first = xpaned; + else + first = next; + } + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (xpaned)); + + if (GTK_IS_WINDOW (toplevel)) + gtk_xpaned_set_saved_focus (focus, GTK_WINDOW (toplevel)->focus_widget); + gtk_xpaned_set_first_xpaned (focus, first); + focus->original_position.x = gtk_xpaned_get_position_x (focus); + focus->original_position.y = gtk_xpaned_get_position_y (focus); + + gtk_widget_grab_focus (GTK_WIDGET (focus)); + } + + return TRUE; +} + +static gboolean gtk_xpaned_toggle_handle_focus (GtkXPaned* xpaned) +{ + /* This function/signal has the wrong name. It is called when you + * press Tab or Shift-Tab and what we do is act as if + * the user pressed Return and then Tab or Shift-Tab + */ + if (gtk_widget_is_focus (GTK_WIDGET (xpaned))) + gtk_xpaned_accept_position (xpaned); + + return FALSE; +} + +/*#define __GTK_XPANED_C__*/ +/*#include "gtkaliasdef.c"*/ diff --git a/lib/gtksheet/gtkxpaned.h b/lib/gtksheet/gtkxpaned.h new file mode 100644 index 00000000..47e752ee --- /dev/null +++ b/lib/gtksheet/gtkxpaned.h @@ -0,0 +1,175 @@ +/******************************************************************************* +**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 +** 10 20 30 40 50 60 70 80 +** +** library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+ +** Copyright (C) 2005-2006 Mirco "MacSlow" Müller +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License as published by the Free Software Foundation; either +** version 2.1 of the License, or (at your option) any later version. +** +** This library is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public +** License along with this library; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +** +** GtkXPaned is based on GtkPaned which was done by... +** +** "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald" +** +** and later modified by... +** +** "the GTK+ Team and others 1997-2000" +** +*******************************************************************************/ + +#ifndef GTK_XPANED_H +#define GTK_XPANED_H + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_XPANED (gtk_xpaned_get_type ()) +#define GTK_XPANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_XPANED, GtkXPaned)) +#define GTK_XPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_XPANED, GtkXPanedClass)) +#define GTK_IS_XPANED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_XPANED)) +#define GTK_IS_XPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XPANED)) +#define GTK_XPANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XPANED, GtkXPanedClass)) + +typedef struct _GtkXPaned GtkXPaned; +typedef struct _GtkXPanedClass GtkXPanedClass; +typedef struct _GtkXPanedPrivate GtkXPanedPrivate; + +typedef enum _GtkXPanedChild +{ + GTK_XPANED_TOP_LEFT = 0, + GTK_XPANED_TOP_RIGHT, + GTK_XPANED_BOTTOM_LEFT, + GTK_XPANED_BOTTOM_RIGHT +} GtkXPanedChild; + +struct _GtkXPaned +{ + GtkContainer container; + + GtkWidget* top_left_child; + GtkWidget* top_right_child; + GtkWidget* bottom_left_child; + GtkWidget* bottom_right_child; + + GdkWindow* handle_east; + GdkWindow* handle_west; + GdkWindow* handle_north; + GdkWindow* handle_south; + GdkWindow* handle_middle; + GdkGC* xor_gc; + GdkCursorType cursor_type_east; + GdkCursorType cursor_type_west; + GdkCursorType cursor_type_north; + GdkCursorType cursor_type_south; + GdkCursorType cursor_type_middle; + + /*< private >*/ + GdkRectangle handle_pos_east; + GdkRectangle handle_pos_west; + GdkRectangle handle_pos_north; + GdkRectangle handle_pos_south; + GdkRectangle handle_pos_middle; + GtkRequisition top_left_child_size; + GtkRequisition top_right_child_size; + GtkRequisition bottom_left_child_size; + GtkRequisition bottom_right_child_size; + + GtkRequisition last_allocation; + GdkPoint min_position; + GdkPoint max_position; + gboolean maximized[4]; + + guint position_set : 1; + guint in_drag_vert : 1; + guint in_drag_horiz : 1; + guint in_drag_vert_and_horiz : 1; + guint top_left_child_shrink : 1; + guint top_left_child_resize : 1; + guint top_right_child_shrink : 1; + guint top_right_child_resize : 1; + guint bottom_left_child_shrink : 1; + guint bottom_left_child_resize : 1; + guint bottom_right_child_shrink : 1; + guint bottom_right_child_resize : 1; + guint in_recursion : 1; + guint handle_prelit : 1; + + GtkWidget* last_top_left_child_focus; + GtkWidget* last_top_right_child_focus; + GtkWidget* last_bottom_left_child_focus; + GtkWidget* last_bottom_right_child_focus; + GtkXPanedPrivate* priv; + + GdkPoint drag_pos; + GdkPoint original_position; + GdkPoint unmaximized_position; +}; + +struct _GtkXPanedClass +{ + GtkContainerClass parent_class; + gboolean (*cycle_child_focus) (GtkXPaned* xpaned, gboolean reverse); + gboolean (*toggle_handle_focus) (GtkXPaned* xpaned); + gboolean (*move_handle) (GtkXPaned* xpaned, GtkScrollType scroll); + gboolean (*cycle_handle_focus) (GtkXPaned* xpaned, gboolean reverse); + gboolean (*accept_position) (GtkXPaned* xpaned); + gboolean (*cancel_position) (GtkXPaned* xpaned); +}; + +GType gtk_xpaned_get_type (void) G_GNUC_CONST; +GtkWidget* gtk_xpaned_new (void); +void gtk_xpaned_add_top_left (GtkXPaned* xpaned, GtkWidget* child); +void gtk_xpaned_add_top_right (GtkXPaned* xpaned, GtkWidget* child); +void gtk_xpaned_add_bottom_left (GtkXPaned* xpaned, GtkWidget* child); +void gtk_xpaned_add_bottom_right (GtkXPaned* xpaned, GtkWidget* child); +void gtk_xpaned_pack_top_left (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink); +void gtk_xpaned_pack_top_right (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink); +void gtk_xpaned_pack_bottom_left (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink); +void gtk_xpaned_pack_bottom_right (GtkXPaned* xpaned, GtkWidget* child, gboolean resize, gboolean shrink); +gint gtk_xpaned_get_position_x (GtkXPaned* xpaned); +gint gtk_xpaned_get_position_y (GtkXPaned* xpaned); +void gtk_xpaned_set_position_x (GtkXPaned* xpaned, gint xposition); +void gtk_xpaned_set_position_y (GtkXPaned* xpaned, gint yposition); +void gtk_xpaned_save_unmaximized_x (GtkXPaned* xpaned); +void gtk_xpaned_save_unmaximized_y (GtkXPaned* xpaned); +gint gtk_xpaned_fetch_unmaximized_x (GtkXPaned* xpaned); +gint gtk_xpaned_fetch_unmaximized_y (GtkXPaned* xpaned); +GtkWidget* gtk_xpaned_get_top_left_child (GtkXPaned* xpaned); +GtkWidget* gtk_xpaned_get_top_right_child (GtkXPaned* xpaned); +GtkWidget* gtk_xpaned_get_bottom_right_child (GtkXPaned* xpaned); +GtkWidget* gtk_xpaned_get_bottom_left_child (GtkXPaned* xpaned); +gboolean gtk_xpaned_maximize_top_left (GtkXPaned* xpaned, gboolean maximize); +gboolean gtk_xpaned_maximize_top_right (GtkXPaned* xpaned, gboolean maximize); +gboolean gtk_xpaned_maximize_bottom_left (GtkXPaned* xpaned, gboolean maximize); +gboolean gtk_xpaned_maximize_bottom_right (GtkXPaned* xpaned, gboolean maximize); + +/* Internal function */ +#if !defined (GTK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) +void gtk_xpaned_compute_position (GtkXPaned* xpaned, + const GtkAllocation* allocation, + GtkRequisition* top_left_child_req, + GtkRequisition* top_right_child_req, + GtkRequisition* bottom_left_child_req, + GtkRequisition* bottom_right_child_req); +#endif /* !GTK_DISABLE_DEPRECATED || GTK_COMPILATION */ +#ifndef GTK_DISABLE_DEPRECATED +#define gtk_xpaned_gutter_size(p,s) (void) 0 +#define gtk_xpaned_set_gutter_size(p,s) (void) 0 +#endif /* GTK_DISABLE_DEPRECATED */ + +G_END_DECLS + +#endif /* GTK_XPANED_H */ diff --git a/po/en_GB.po b/po/en_GB.po index 59c50670..c602e83f 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PSPP 0.7.0\n" "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n" -"POT-Creation-Date: 2008-11-08 12:59+0900\n" +"POT-Creation-Date: 2008-11-11 13:13+0900\n" "PO-Revision-Date: 2008-11-05 08:17+0900\n" "Last-Translator: John Darrington \n" "Language-Team: John Darrington \n" @@ -323,13 +323,13 @@ msgid "%s variables are not compatible with %s format %s." msgstr "" #: src/data/format.c:327 src/data/sys-file-reader.c:655 -#: src/ui/gui/data-editor.glade:1190 src/ui/gui/psppire.glade:2176 +#: src/ui/gui/data-editor.glade:1197 src/ui/gui/psppire.glade:2176 #: src/ui/gui/psppire-var-store.c:605 msgid "String" msgstr "" #: src/data/format.c:327 src/data/sys-file-reader.c:655 -#: src/ui/gui/data-editor.glade:1079 src/ui/gui/psppire.glade:2131 +#: src/ui/gui/data-editor.glade:1086 src/ui/gui/psppire.glade:2131 #: src/ui/gui/psppire-var-store.c:598 msgid "Numeric" msgstr "" @@ -3388,7 +3388,7 @@ msgstr "" msgid "Cum" msgstr "" -#: src/language/stats/frequencies.q:1056 src/output/charts/plot-hist.c:138 +#: src/language/stats/frequencies.q:1056 src/output/charts/plot-hist.c:140 msgid "Frequency" msgstr "" @@ -4016,28 +4016,28 @@ msgstr "" msgid "Only USE ALL is currently implemented." msgstr "" -#: src/language/utilities/include.c:91 +#: src/language/utilities/include.c:90 msgid "Expecting BATCH or INTERACTIVE after SYNTAX." msgstr "" -#: src/language/utilities/include.c:108 +#: src/language/utilities/include.c:107 msgid "Expecting YES or NO after CD." msgstr "" -#: src/language/utilities/include.c:125 +#: src/language/utilities/include.c:124 msgid "Expecting CONTINUE or STOP after ERROR." msgstr "" -#: src/language/utilities/include.c:132 +#: src/language/utilities/include.c:131 #, c-format msgid "Unexpected token: `%s'." msgstr "" -#: src/language/utilities/include.c:177 +#: src/language/utilities/include.c:176 msgid "expecting file name" msgstr "" -#: src/language/utilities/include.c:189 +#: src/language/utilities/include.c:188 #, c-format msgid "Can't find `%s' in include file search path." msgstr "" @@ -4457,7 +4457,7 @@ msgstr "" msgid "creating \"%s\"" msgstr "" -#: src/output/charts/plot-hist.c:136 +#: src/output/charts/plot-hist.c:138 msgid "HISTOGRAM" msgstr "" @@ -4834,329 +4834,337 @@ msgstr "" msgid "Style of bevel around the custom entry button" msgstr "" -#: src/ui/gui/data-editor.c:150 +#: src/ui/gui/data-editor.c:152 msgid "Transformations Pending" msgstr "" -#: src/ui/gui/data-editor.c:323 +#: src/ui/gui/data-editor.c:325 msgid "_Labels" msgstr "" -#: src/ui/gui/data-editor.c:324 +#: src/ui/gui/data-editor.c:326 msgid "Show/hide value labels" msgstr "" -#: src/ui/gui/data-editor.c:342 src/ui/gui/data-editor.c:361 -#: src/ui/gui/data-editor.c:1512 src/ui/gui/data-editor.c:1566 +#: src/ui/gui/data-editor.c:344 src/ui/gui/data-editor.c:363 +#: src/ui/gui/data-editor.c:1539 src/ui/gui/data-editor.c:1593 msgid "Clear" msgstr "" -#: src/ui/gui/data-editor.c:343 +#: src/ui/gui/data-editor.c:345 msgid "Delete the cases at the selected position(s)" msgstr "" -#: src/ui/gui/data-editor.c:362 +#: src/ui/gui/data-editor.c:364 msgid "Delete the variables at the selected position(s)" msgstr "" -#: src/ui/gui/data-editor.c:377 +#: src/ui/gui/data-editor.c:379 msgid "Insert _Variable" msgstr "" -#: src/ui/gui/data-editor.c:378 +#: src/ui/gui/data-editor.c:380 msgid "Create a new variable at the current position" msgstr "" -#: src/ui/gui/data-editor.c:396 +#: src/ui/gui/data-editor.c:398 msgid "Insert Ca_se" msgstr "" -#: src/ui/gui/data-editor.c:397 +#: src/ui/gui/data-editor.c:399 msgid "Create a new case at the current position" msgstr "" -#: src/ui/gui/data-editor.c:417 +#: src/ui/gui/data-editor.c:419 msgid "_Goto Case" msgstr "" -#: src/ui/gui/data-editor.c:418 +#: src/ui/gui/data-editor.c:420 msgid "Jump to a Case in the Data Sheet" msgstr "" -#: src/ui/gui/data-editor.c:437 +#: src/ui/gui/data-editor.c:439 msgid "_Weights" msgstr "" -#: src/ui/gui/data-editor.c:438 +#: src/ui/gui/data-editor.c:440 msgid "Weight cases by variable" msgstr "" -#: src/ui/gui/data-editor.c:447 src/ui/gui/data-editor.glade:319 +#: src/ui/gui/data-editor.c:449 src/ui/gui/data-editor.glade:319 msgid "_Transpose" msgstr "" -#: src/ui/gui/data-editor.c:448 +#: src/ui/gui/data-editor.c:450 msgid "Transpose the cases with the variables" msgstr "" -#: src/ui/gui/data-editor.c:459 +#: src/ui/gui/data-editor.c:461 msgid "S_plit" msgstr "" -#: src/ui/gui/data-editor.c:460 +#: src/ui/gui/data-editor.c:462 msgid "Split the active file" msgstr "" -#: src/ui/gui/data-editor.c:470 +#: src/ui/gui/data-editor.c:472 msgid "_Sort" msgstr "" -#: src/ui/gui/data-editor.c:471 +#: src/ui/gui/data-editor.c:473 msgid "Sort cases in the active file" msgstr "" -#: src/ui/gui/data-editor.c:479 src/ui/gui/data-editor.glade:340 +#: src/ui/gui/data-editor.c:481 src/ui/gui/data-editor.glade:340 msgid "Select _Cases" msgstr "" -#: src/ui/gui/data-editor.c:480 +#: src/ui/gui/data-editor.c:482 msgid "Select cases from the active file" msgstr "" -#: src/ui/gui/data-editor.c:489 src/ui/gui/data-editor.glade:369 +#: src/ui/gui/data-editor.c:491 src/ui/gui/data-editor.glade:369 msgid "_Compute" msgstr "" -#: src/ui/gui/data-editor.c:490 +#: src/ui/gui/data-editor.c:492 msgid "Compute new values for a variable" msgstr "" -#: src/ui/gui/data-editor.c:498 +#: src/ui/gui/data-editor.c:500 msgid "Oneway _ANOVA" msgstr "" -#: src/ui/gui/data-editor.c:499 +#: src/ui/gui/data-editor.c:501 msgid "Perform one way analysis of variance" msgstr "" -#: src/ui/gui/data-editor.c:507 src/ui/gui/data-editor.glade:496 +#: src/ui/gui/data-editor.c:509 src/ui/gui/data-editor.glade:496 msgid "_Independent Samples T Test" msgstr "" -#: src/ui/gui/data-editor.c:508 +#: src/ui/gui/data-editor.c:510 msgid "Calculate T Test for samples from independent groups" msgstr "" -#: src/ui/gui/data-editor.c:517 src/ui/gui/data-editor.glade:504 +#: src/ui/gui/data-editor.c:519 src/ui/gui/data-editor.glade:504 msgid "_Paired Samples T Test" msgstr "" -#: src/ui/gui/data-editor.c:518 +#: src/ui/gui/data-editor.c:520 msgid "Calculate T Test for paired samples" msgstr "" -#: src/ui/gui/data-editor.c:527 +#: src/ui/gui/data-editor.c:529 msgid "One _Sample T Test" msgstr "" -#: src/ui/gui/data-editor.c:528 +#: src/ui/gui/data-editor.c:530 msgid "Calculate T Test for sample from a single distribution" msgstr "" -#: src/ui/gui/data-editor.c:537 src/ui/gui/data-editor.glade:593 +#: src/ui/gui/data-editor.c:539 src/ui/gui/data-editor.glade:593 msgid "Data File _Comments" msgstr "" -#: src/ui/gui/data-editor.c:538 +#: src/ui/gui/data-editor.c:540 msgid "Commentary text for the data file" msgstr "" -#: src/ui/gui/data-editor.c:546 src/ui/gui/data-editor.glade:228 +#: src/ui/gui/data-editor.c:548 src/ui/gui/data-editor.glade:228 msgid "_Find" msgstr "" -#: src/ui/gui/data-editor.c:547 +#: src/ui/gui/data-editor.c:549 msgid "Find Case" msgstr "" -#: src/ui/gui/data-editor.c:556 src/ui/gui/data-editor.glade:377 +#: src/ui/gui/data-editor.c:558 src/ui/gui/data-editor.glade:377 msgid "Ran_k Cases" msgstr "" -#: src/ui/gui/data-editor.c:557 +#: src/ui/gui/data-editor.c:559 msgid "Rank Cases" msgstr "" -#: src/ui/gui/data-editor.c:566 src/ui/gui/data-editor.glade:389 +#: src/ui/gui/data-editor.c:568 src/ui/gui/data-editor.glade:389 msgid "Recode into _Same Variables" msgstr "" -#: src/ui/gui/data-editor.c:567 +#: src/ui/gui/data-editor.c:569 msgid "Recode values into the same Variables" msgstr "" -#: src/ui/gui/data-editor.c:576 src/ui/gui/data-editor.glade:396 +#: src/ui/gui/data-editor.c:578 src/ui/gui/data-editor.glade:396 msgid "Recode into _Different Variables" msgstr "" -#: src/ui/gui/data-editor.c:577 +#: src/ui/gui/data-editor.c:579 msgid "Recode values into different Variables" msgstr "" -#: src/ui/gui/data-editor.c:586 src/ui/gui/data-editor.glade:293 +#: src/ui/gui/data-editor.c:588 src/ui/gui/data-editor.glade:293 #: src/ui/gui/data-editor.glade:584 msgid "_Variables" msgstr "" -#: src/ui/gui/data-editor.c:587 +#: src/ui/gui/data-editor.c:589 msgid "Jump to Variable" msgstr "" -#: src/ui/gui/data-editor.c:595 src/ui/gui/data-editor.glade:450 +#: src/ui/gui/data-editor.c:597 src/ui/gui/data-editor.glade:450 #: src/ui/gui/oneway.glade:179 msgid "_Descriptives" msgstr "" -#: src/ui/gui/data-editor.c:596 +#: src/ui/gui/data-editor.c:598 msgid "Calculate descriptive statistics (mean, variance, ...)" msgstr "" -#: src/ui/gui/data-editor.c:605 src/ui/gui/data-editor.glade:442 +#: src/ui/gui/data-editor.c:607 src/ui/gui/data-editor.glade:442 msgid "_Frequencies" msgstr "" -#: src/ui/gui/data-editor.c:606 +#: src/ui/gui/data-editor.c:608 msgid "Generate frequency statistics" msgstr "" -#: src/ui/gui/data-editor.c:614 src/ui/gui/data-editor.glade:466 +#: src/ui/gui/data-editor.c:616 src/ui/gui/data-editor.glade:466 msgid "_Crosstabs" msgstr "" -#: src/ui/gui/data-editor.c:615 +#: src/ui/gui/data-editor.c:617 msgid "Generate crosstabulations" msgstr "" -#: src/ui/gui/data-editor.c:624 src/ui/gui/data-editor.glade:458 +#: src/ui/gui/data-editor.c:626 src/ui/gui/data-editor.glade:458 msgid "_Explore" msgstr "" -#: src/ui/gui/data-editor.c:625 +#: src/ui/gui/data-editor.c:627 msgid "Examine Data by Factors" msgstr "" -#: src/ui/gui/data-editor.c:634 src/ui/gui/data-editor.glade:532 +#: src/ui/gui/data-editor.c:636 src/ui/gui/data-editor.glade:532 msgid "Linear _Regression" msgstr "" -#: src/ui/gui/data-editor.c:635 +#: src/ui/gui/data-editor.c:637 msgid "Estimate parameters of the linear model" msgstr "" -#: src/ui/gui/data-editor.c:1027 +#: src/ui/gui/data-editor.c:921 +msgid "_Split Window" +msgstr "" + +#: src/ui/gui/data-editor.c:922 +msgid "Split the window vertically and horizontally" +msgstr "" + +#: src/ui/gui/data-editor.c:1042 msgid "Font Selection" msgstr "" -#: src/ui/gui/data-editor.c:1099 +#: src/ui/gui/data-editor.c:1126 msgid "No Split" msgstr "" -#: src/ui/gui/data-editor.c:1108 +#: src/ui/gui/data-editor.c:1135 msgid "Split by " msgstr "" -#: src/ui/gui/data-editor.c:1133 +#: src/ui/gui/data-editor.c:1160 msgid "Filter off" msgstr "" -#: src/ui/gui/data-editor.c:1145 +#: src/ui/gui/data-editor.c:1172 #, c-format msgid "Filter by %s" msgstr "" -#: src/ui/gui/data-editor.c:1163 +#: src/ui/gui/data-editor.c:1190 msgid "Weights off" msgstr "" -#: src/ui/gui/data-editor.c:1175 +#: src/ui/gui/data-editor.c:1202 #, c-format msgid "Weight by %s" msgstr "" -#: src/ui/gui/data-editor.c:1198 src/ui/gui/data-editor.c:1445 -#: src/ui/gui/data-editor.glade:660 +#: src/ui/gui/data-editor.c:1225 src/ui/gui/data-editor.c:1472 +#: src/ui/gui/data-editor.glade:667 msgid "Open" msgstr "" -#: src/ui/gui/data-editor.c:1199 +#: src/ui/gui/data-editor.c:1226 msgid "Open a data file" msgstr "" -#: src/ui/gui/data-editor.c:1207 src/ui/gui/data-editor.c:1323 -#: src/ui/gui/data-editor.glade:670 +#: src/ui/gui/data-editor.c:1234 src/ui/gui/data-editor.c:1350 +#: src/ui/gui/data-editor.glade:677 msgid "Save" msgstr "" -#: src/ui/gui/data-editor.c:1208 src/ui/gui/data-editor.c:1218 +#: src/ui/gui/data-editor.c:1235 src/ui/gui/data-editor.c:1245 msgid "Save data to file" msgstr "" -#: src/ui/gui/data-editor.c:1217 +#: src/ui/gui/data-editor.c:1244 msgid "Save As" msgstr "" -#: src/ui/gui/data-editor.c:1226 src/ui/gui/recode-dialog.c:928 +#: src/ui/gui/data-editor.c:1253 src/ui/gui/recode-dialog.c:928 #: src/ui/gui/recode-dialog.c:1023 msgid "New" msgstr "" -#: src/ui/gui/data-editor.c:1227 +#: src/ui/gui/data-editor.c:1254 msgid "New data file" msgstr "" -#: src/ui/gui/data-editor.c:1235 +#: src/ui/gui/data-editor.c:1262 msgid "_Import Text Data" msgstr "" -#: src/ui/gui/data-editor.c:1236 +#: src/ui/gui/data-editor.c:1263 msgid "Import text data file" msgstr "" -#: src/ui/gui/data-editor.c:1331 src/ui/gui/data-editor.c:1453 +#: src/ui/gui/data-editor.c:1358 src/ui/gui/data-editor.c:1480 msgid "System Files (*.sav)" msgstr "" -#: src/ui/gui/data-editor.c:1337 src/ui/gui/data-editor.c:1459 +#: src/ui/gui/data-editor.c:1364 src/ui/gui/data-editor.c:1486 msgid "Portable Files (*.por) " msgstr "" -#: src/ui/gui/data-editor.c:1343 src/ui/gui/data-editor.c:1465 +#: src/ui/gui/data-editor.c:1370 src/ui/gui/data-editor.c:1492 #: src/ui/gui/syntax-editor.c:138 src/ui/gui/syntax-editor.c:522 msgid "All Files" msgstr "" -#: src/ui/gui/data-editor.c:1351 +#: src/ui/gui/data-editor.c:1378 msgid "System File" msgstr "" -#: src/ui/gui/data-editor.c:1356 +#: src/ui/gui/data-editor.c:1383 msgid "Portable File" msgstr "" -#: src/ui/gui/data-editor.c:1503 +#: src/ui/gui/data-editor.c:1530 msgid "Sort Ascending" msgstr "" -#: src/ui/gui/data-editor.c:1506 +#: src/ui/gui/data-editor.c:1533 msgid "Sort Descending" msgstr "" -#: src/ui/gui/data-editor.c:1509 src/ui/gui/data-editor.glade:150 -#: src/ui/gui/data-editor.glade:801 +#: src/ui/gui/data-editor.c:1536 src/ui/gui/data-editor.glade:150 +#: src/ui/gui/data-editor.glade:808 msgid "Insert Variable" msgstr "" -#: src/ui/gui/data-editor.c:1563 src/ui/gui/data-editor.glade:789 +#: src/ui/gui/data-editor.c:1590 src/ui/gui/data-editor.glade:796 msgid "Insert Case" msgstr "" @@ -5197,7 +5205,7 @@ msgstr "" msgid "Insert Cases" msgstr "" -#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:738 +#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:745 msgid "Go To Case" msgstr "" @@ -5299,173 +5307,177 @@ msgstr "" msgid "_Minimize All Windows" msgstr "_Minimise All Windows" -#: src/ui/gui/data-editor.glade:622 src/ui/gui/output-viewer.glade:99 +#: src/ui/gui/data-editor.glade:618 +msgid "_Split" +msgstr "" + +#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:99 #: src/ui/gui/syntax-editor.glade:254 msgid "_Help" msgstr "" -#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:106 +#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:106 #: src/ui/gui/syntax-editor.glade:262 msgid "_Reference Manual" msgstr "" -#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:113 +#: src/ui/gui/data-editor.glade:643 src/ui/gui/output-viewer.glade:113 #: src/ui/gui/syntax-editor.glade:269 msgid "_About" msgstr "" -#: src/ui/gui/data-editor.glade:680 +#: src/ui/gui/data-editor.glade:687 msgid "Print" msgstr "" -#: src/ui/gui/data-editor.glade:690 +#: src/ui/gui/data-editor.glade:697 msgid "Recall" msgstr "" -#: src/ui/gui/data-editor.glade:708 +#: src/ui/gui/data-editor.glade:715 msgid "Undo" msgstr "" -#: src/ui/gui/data-editor.glade:718 +#: src/ui/gui/data-editor.glade:725 msgid "Redo" msgstr "" -#: src/ui/gui/data-editor.glade:748 +#: src/ui/gui/data-editor.glade:755 msgid "Variables" msgstr "" -#: src/ui/gui/data-editor.glade:769 +#: src/ui/gui/data-editor.glade:776 msgid "Find" msgstr "" -#: src/ui/gui/data-editor.glade:821 +#: src/ui/gui/data-editor.glade:828 msgid "Split File" msgstr "" -#: src/ui/gui/data-editor.glade:832 +#: src/ui/gui/data-editor.glade:839 msgid "Weight Cases" msgstr "" -#: src/ui/gui/data-editor.glade:844 +#: src/ui/gui/data-editor.glade:851 msgid "Select Cases" msgstr "" -#: src/ui/gui/data-editor.glade:864 src/ui/gui/data-editor.glade:1452 -#: src/ui/gui/data-editor.glade:1633 +#: src/ui/gui/data-editor.glade:871 src/ui/gui/data-editor.glade:1459 +#: src/ui/gui/data-editor.glade:1640 msgid "Value Labels" msgstr "" -#: src/ui/gui/data-editor.glade:875 +#: src/ui/gui/data-editor.glade:882 msgid "Use Sets" msgstr "" -#: src/ui/gui/data-editor.glade:907 +#: src/ui/gui/data-editor.glade:914 msgid "Information Area" msgstr "" -#: src/ui/gui/data-editor.glade:926 +#: src/ui/gui/data-editor.glade:933 msgid "Processor Area" msgstr "" -#: src/ui/gui/data-editor.glade:951 +#: src/ui/gui/data-editor.glade:958 msgid "Case Counter Area" msgstr "" -#: src/ui/gui/data-editor.glade:976 +#: src/ui/gui/data-editor.glade:983 msgid "Filter Use Status Area" msgstr "" -#: src/ui/gui/data-editor.glade:1002 +#: src/ui/gui/data-editor.glade:1009 msgid "Weight Status Area" msgstr "" -#: src/ui/gui/data-editor.glade:1028 +#: src/ui/gui/data-editor.glade:1035 msgid "Split File Status Area" msgstr "" -#: src/ui/gui/data-editor.glade:1058 +#: src/ui/gui/data-editor.glade:1065 msgid "Variable Type" msgstr "" -#: src/ui/gui/data-editor.glade:1094 src/ui/gui/psppire-var-store.c:599 +#: src/ui/gui/data-editor.glade:1101 src/ui/gui/psppire-var-store.c:599 msgid "Comma" msgstr "" -#: src/ui/gui/data-editor.glade:1110 src/ui/gui/psppire-var-store.c:600 +#: src/ui/gui/data-editor.glade:1117 src/ui/gui/psppire-var-store.c:600 msgid "Dot" msgstr "" -#: src/ui/gui/data-editor.glade:1126 +#: src/ui/gui/data-editor.glade:1133 msgid "Scientific notation" msgstr "" -#: src/ui/gui/data-editor.glade:1142 src/ui/gui/psppire-var-store.c:602 +#: src/ui/gui/data-editor.glade:1149 src/ui/gui/psppire-var-store.c:602 msgid "Date" msgstr "" -#: src/ui/gui/data-editor.glade:1158 src/ui/gui/psppire-var-store.c:603 +#: src/ui/gui/data-editor.glade:1165 src/ui/gui/psppire-var-store.c:603 msgid "Dollar" msgstr "" -#: src/ui/gui/data-editor.glade:1174 +#: src/ui/gui/data-editor.glade:1181 msgid "Custom currency" msgstr "" -#: src/ui/gui/data-editor.glade:1268 +#: src/ui/gui/data-editor.glade:1275 msgid "positive" msgstr "" -#: src/ui/gui/data-editor.glade:1274 +#: src/ui/gui/data-editor.glade:1281 msgid "negative" msgstr "" -#: src/ui/gui/data-editor.glade:1287 +#: src/ui/gui/data-editor.glade:1294 msgid "Sample" msgstr "" -#: src/ui/gui/data-editor.glade:1337 +#: src/ui/gui/data-editor.glade:1344 msgid "Width:" msgstr "" -#: src/ui/gui/data-editor.glade:1381 +#: src/ui/gui/data-editor.glade:1388 msgid "Decimal Places:" msgstr "" -#: src/ui/gui/data-editor.glade:1550 +#: src/ui/gui/data-editor.glade:1557 msgid "Value Label:" msgstr "" -#: src/ui/gui/data-editor.glade:1563 src/ui/gui/psppire.glade:2544 +#: src/ui/gui/data-editor.glade:1570 src/ui/gui/psppire.glade:2544 #: src/ui/gui/recode.glade:185 msgid "Value:" msgstr "" -#: src/ui/gui/data-editor.glade:1700 src/ui/gui/examine.glade:423 +#: src/ui/gui/data-editor.glade:1707 src/ui/gui/examine.glade:423 #: src/ui/gui/t-test.glade:460 msgid "Missing Values" msgstr "" -#: src/ui/gui/data-editor.glade:1718 +#: src/ui/gui/data-editor.glade:1725 msgid "_Range plus one optional discrete missing value" msgstr "" -#: src/ui/gui/data-editor.glade:1743 +#: src/ui/gui/data-editor.glade:1750 msgid "_Low:" msgstr "" -#: src/ui/gui/data-editor.glade:1772 +#: src/ui/gui/data-editor.glade:1779 msgid "_High:" msgstr "" -#: src/ui/gui/data-editor.glade:1813 +#: src/ui/gui/data-editor.glade:1820 msgid "Di_screte value:" msgstr "" -#: src/ui/gui/data-editor.glade:1860 +#: src/ui/gui/data-editor.glade:1867 msgid "_No missing values" msgstr "" -#: src/ui/gui/data-editor.glade:1878 +#: src/ui/gui/data-editor.glade:1885 msgid "_Discrete missing values" msgstr "" @@ -5785,15 +5797,20 @@ msgstr "" msgid "Cannot open %s: %s.\n" msgstr "" -#: src/ui/gui/psppire-data-editor.c:604 +#: src/ui/gui/psppire.c:270 +#, c-format +msgid "%s is neither a system nor portable file" +msgstr "" + +#: src/ui/gui/psppire-data-editor.c:703 msgid "Data View" msgstr "" -#: src/ui/gui/psppire-data-editor.c:607 +#: src/ui/gui/psppire-data-editor.c:706 msgid "Variable View" msgstr "" -#: src/ui/gui/psppire-data-store.c:828 +#: src/ui/gui/psppire-data-store.c:829 msgid "var" msgstr "" diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index f7df21c7..d4cbae1e 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -81,6 +81,8 @@ static void on_insert_variable (GtkAction *, gpointer data); static void insert_case (GtkAction *a, gpointer data); static void toggle_value_labels (GtkToggleAction *a, gpointer data); +static void toggle_split_window (GtkToggleAction *ta, gpointer data); + /* Callback for when the dictionary changes properties*/ static void on_weight_change (GObject *, gint, gpointer); @@ -914,6 +916,19 @@ new_data_editor (void) "activate", G_CALLBACK (minimise_all_windows), NULL); + de->toggle_split_window = + gtk_toggle_action_new ("toggle-split-window", + _("_Split Window"), + _("Split the window vertically and horizontally"), + "pspp-split-window"); + + g_signal_connect (de->toggle_split_window, "toggled", + G_CALLBACK (toggle_split_window), + de); + + gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window), + get_widget_assert (de->xml, + "windows_split")); de->data_sheet_variable_popup_menu = GTK_MENU (create_data_sheet_variable_popup_menu (de)); @@ -1056,6 +1071,18 @@ toggle_value_labels (GtkToggleAction *ta, gpointer data) +static void +toggle_split_window (GtkToggleAction *ta, gpointer data) +{ + struct data_editor *de = data; + + psppire_data_editor_split_window (de->data_editor, + gtk_toggle_action_get_active (ta)); +} + + + + static void file_quit (GtkCheckMenuItem *menuitem, gpointer data) { diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index cdf6080e..deff3bb5 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -612,6 +612,13 @@ True + + + True + _Split + True + + diff --git a/src/ui/gui/data-editor.h b/src/ui/gui/data-editor.h index 9ea0e916..237b6769 100644 --- a/src/ui/gui/data-editor.h +++ b/src/ui/gui/data-editor.h @@ -61,6 +61,8 @@ struct data_editor GtkAction *invoke_oneway_anova_dialog; GtkAction *invoke_t_test_one_sample_dialog; + GtkToggleAction *toggle_split_window; + /* Actions which do things */ GtkAction *insert_variable; diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c index 3a6152a5..7d0897f9 100644 --- a/src/ui/gui/psppire-data-editor.c +++ b/src/ui/gui/psppire-data-editor.c @@ -26,11 +26,15 @@ #include "psppire-data-store.h" #include "helper.h" +#include #include #define _(msgid) gettext (msgid) #define N_(msgid) msgid +static void psppire_data_editor_remove_split (PsppireDataEditor *de); +static void psppire_data_editor_set_split (PsppireDataEditor *de); + enum { DATA_SELECTION_CHANGED, DATA_AVAILABLE_CHANGED, @@ -143,16 +147,16 @@ on_var_row_clicked (PsppireDataEditor *de, gint row, gpointer data) gtk_notebook_set_current_page (GTK_NOTEBOOK(de), PSPPIRE_DATA_EDITOR_DATA_VIEW); - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), ¤t_row, ¤t_column); - gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), current_row, row); + gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), current_row, row); - gtk_sheet_get_visible_range (GTK_SHEET (de->data_sheet), &visible_range); + gtk_sheet_get_visible_range (GTK_SHEET (de->data_sheet[0]), &visible_range); if ( row < visible_range.col0 || row > visible_range.coli) { - gtk_sheet_moveto (GTK_SHEET (de->data_sheet), + gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), current_row, row, 0, 0); } @@ -171,7 +175,8 @@ enum PROP_VALUE_LABELS, PROP_CURRENT_CASE, PROP_CURRENT_VAR, - PROP_DATA_SELECTED + PROP_DATA_SELECTED, + PROP_SPLIT_WINDOW }; static void @@ -180,20 +185,25 @@ psppire_data_editor_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + int i; PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (object); switch (prop_id) { + case PROP_SPLIT_WINDOW: + psppire_data_editor_split_window (de, g_value_get_boolean (value)); + break; case PROP_DATA_STORE: if ( de->data_store) g_object_unref (de->data_store); de->data_store = g_value_get_pointer (value); g_object_ref (de->data_store); - g_object_set (de->data_sheet, - "row-geometry", de->data_store, - "column-geometry", de->data_store, - "model", de->data_store, - NULL); + for (i = 0 ; i < 4 ; ++i ) + g_object_set (de->data_sheet[i], + "row-geometry", de->data_store, + "column-geometry", de->data_store, + "model", de->data_store, + NULL); break; case PROP_VAR_STORE: if ( de->var_store) g_object_unref (de->var_store); @@ -209,7 +219,7 @@ psppire_data_editor_set_property (GObject *object, { GObject *menu = g_value_get_object (value); - g_signal_connect (de->data_sheet, "button-event-column", + g_signal_connect (de->data_sheet[0], "button-event-column", G_CALLBACK (popup_variable_menu), menu); } break; @@ -217,7 +227,7 @@ psppire_data_editor_set_property (GObject *object, { GObject *menu = g_value_get_object (value); - g_signal_connect (de->data_sheet, "button-event-row", + g_signal_connect (de->data_sheet[0], "button-event-row", G_CALLBACK (popup_cases_menu), menu); } break; @@ -228,9 +238,9 @@ psppire_data_editor_set_property (GObject *object, switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (object))) { case PSPPIRE_DATA_EDITOR_DATA_VIEW: - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col); - gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), row, var); - gtk_sheet_moveto (GTK_SHEET (de->data_sheet), row, var, 0.5, 0.5); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col); + gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), row, var); + gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), row, var, 0.5, 0.5); break; case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW: gtk_sheet_get_active_cell (GTK_SHEET (de->var_sheet), &row, &col); @@ -247,9 +257,9 @@ psppire_data_editor_set_property (GObject *object, { gint row, col; gint case_num = g_value_get_long (value); - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col); - gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet), case_num, col); - gtk_sheet_moveto (GTK_SHEET (de->data_sheet), case_num, col, 0.5, 0.5); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col); + gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[0]), case_num, col); + gtk_sheet_moveto (GTK_SHEET (de->data_sheet[0]), case_num, col, 0.5, 0.5); } break; case PROP_VALUE_LABELS: @@ -274,6 +284,9 @@ psppire_data_editor_get_property (GObject *object, switch (prop_id) { + case PROP_SPLIT_WINDOW: + g_value_set_boolean (value, de->split); + break; case PROP_DATA_STORE: g_value_set_pointer (value, de->data_store); break; @@ -283,14 +296,14 @@ psppire_data_editor_get_property (GObject *object, case PROP_CURRENT_CASE: { gint row, column; - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column); g_value_set_long (value, row); } break; case PROP_CURRENT_VAR: { gint row, column; - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column); g_value_set_long (value, column); } break; @@ -315,6 +328,7 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass) GParamSpec *current_case_spec; GParamSpec *current_var_spec; GParamSpec *data_selected_spec; + GParamSpec *split_window_spec; GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); @@ -419,6 +433,17 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass) + split_window_spec = + g_param_spec_boolean ("split", + "Split Window", + "True iff the data sheet is split", + FALSE, + G_PARAM_READABLE | G_PARAM_WRITABLE); + + g_object_class_install_property (object_class, + PROP_SPLIT_WINDOW, + split_window_spec); + data_editor_signals [DATA_SELECTION_CHANGED] = g_signal_new ("data-selection-changed", G_TYPE_FROM_CLASS (klass), @@ -533,7 +558,7 @@ datum_entry_activate (GtkEntry *entry, gpointer data) const gchar *text = gtk_entry_get_text (entry); - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &column); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &column); if ( row == -1 || column == -1) return; @@ -541,7 +566,7 @@ datum_entry_activate (GtkEntry *entry, gpointer data) psppire_data_store_set_string (de->data_store, text, row, column); } - +static gboolean on_data_sheet_activate (GtkWidget *sheet, gint i, gint j, PsppireDataEditor *de); static void on_activate (PsppireDataEditor *de); static void on_deactivate (PsppireDataEditor *de); static gboolean on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p, gint pagenum, gpointer data); @@ -563,16 +588,88 @@ on_map (GtkWidget *w) } +static void +init_sheet (PsppireDataEditor *de, int i, + GtkAdjustment *hadj, GtkAdjustment *vadj) +{ + de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj); + + de->data_sheet[i] = gtk_sheet_new (NULL, NULL, NULL); + + g_object_set (de->sheet_bin[i], + "border-width", 3, + "shadow-type", GTK_SHADOW_ETCHED_IN, + NULL); + + gtk_container_add (GTK_CONTAINER (de->sheet_bin[i]), de->data_sheet[i]); + + gtk_widget_show (de->sheet_bin[i]); +} + + +static void +init_data_sheet (PsppireDataEditor *de) +{ + GtkAdjustment *va0, *ha0; + GtkAdjustment *va1, *ha1; + GtkWidget *sheet ; + + de->split = TRUE; + de->paned = gtk_xpaned_new (); + + init_sheet (de, 0, NULL, NULL); + gtk_widget_show (de->sheet_bin[0]); + va0 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[0])); + ha0 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[0])); + + g_object_set (de->sheet_bin[0], "vscrollbar-policy", GTK_POLICY_NEVER, NULL); + g_object_set (de->sheet_bin[0], "hscrollbar-policy", GTK_POLICY_NEVER, NULL); + + init_sheet (de, 1, NULL, va0); + gtk_widget_show (de->sheet_bin[1]); + sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[1])); + gtk_sheet_hide_row_titles (GTK_SHEET (sheet)); + ha1 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[1])); + g_object_set (de->sheet_bin[1], "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL); + g_object_set (de->sheet_bin[1], "hscrollbar-policy", GTK_POLICY_NEVER, NULL); + + init_sheet (de, 2, ha0, NULL); + gtk_widget_show (de->sheet_bin[2]); + sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[2])); + gtk_sheet_hide_column_titles (GTK_SHEET (sheet)); + g_object_set (de->sheet_bin[2], "vscrollbar-policy", GTK_POLICY_NEVER, NULL); + g_object_set (de->sheet_bin[2], "hscrollbar-policy", GTK_POLICY_ALWAYS, NULL); + va1 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (de->sheet_bin[2])); + + init_sheet (de, 3, ha1, va1); + gtk_widget_show (de->sheet_bin[3]); + sheet = gtk_bin_get_child (GTK_BIN (de->sheet_bin[3])); + gtk_sheet_hide_column_titles (GTK_SHEET (sheet)); + gtk_sheet_hide_row_titles (GTK_SHEET (sheet)); + g_object_set (de->sheet_bin[3], "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL); + g_object_set (de->sheet_bin[3], "hscrollbar-policy", GTK_POLICY_ALWAYS, NULL); + + gtk_xpaned_pack_top_left (GTK_XPANED (de->paned), de->sheet_bin[0], TRUE, TRUE); + gtk_xpaned_pack_top_right (GTK_XPANED (de->paned), de->sheet_bin[1], TRUE, TRUE); + gtk_xpaned_pack_bottom_left (GTK_XPANED (de->paned), de->sheet_bin[2], TRUE, TRUE); + gtk_xpaned_pack_bottom_right (GTK_XPANED (de->paned), de->sheet_bin[3], TRUE, TRUE); + + gtk_xpaned_set_position_y (GTK_XPANED (de->paned), 150); + gtk_xpaned_set_position_x (GTK_XPANED (de->paned), 350); +} + + static void psppire_data_editor_init (PsppireDataEditor *de) { - GtkWidget *vbox = gtk_vbox_new (FALSE, 0); + int i; + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - GtkWidget *sw_ds = gtk_scrolled_window_new (NULL, NULL); GtkWidget *sw_vs = gtk_scrolled_window_new (NULL, NULL); + init_data_sheet (de); - de->data_sheet = gtk_sheet_new (NULL, NULL, NULL); + de->data_vbox = gtk_vbox_new (FALSE, 0); de->var_sheet = psppire_var_sheet_new (); g_object_set (de, "tab-pos", GTK_POS_BOTTOM, NULL); @@ -594,19 +691,21 @@ psppire_data_editor_init (PsppireDataEditor *de) gtk_widget_show_all (sw_vs); - gtk_container_add (GTK_CONTAINER (sw_ds), de->data_sheet); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), sw_ds, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (de->data_vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (de->data_vbox), de->paned, TRUE, TRUE, 0); + - gtk_widget_show_all (vbox); + psppire_data_editor_remove_split (de); - gtk_notebook_append_page (GTK_NOTEBOOK (de), vbox, + gtk_widget_show_all (de->data_vbox); + + gtk_notebook_append_page (GTK_NOTEBOOK (de), de->data_vbox, gtk_label_new_with_mnemonic (_("Data View"))); gtk_notebook_append_page (GTK_NOTEBOOK (de), sw_vs, gtk_label_new_with_mnemonic (_("Variable View"))); - g_signal_connect (de->data_sheet, "activate", + g_signal_connect (de->data_sheet[0], "activate", G_CALLBACK (update_data_ref_entry), de); @@ -615,7 +714,7 @@ psppire_data_editor_init (PsppireDataEditor *de) de); - g_signal_connect_swapped (de->data_sheet, + g_signal_connect_swapped (de->data_sheet[0], "double-click-column", G_CALLBACK (on_data_column_clicked), de); @@ -625,22 +724,27 @@ psppire_data_editor_init (PsppireDataEditor *de) G_CALLBACK (on_var_row_clicked), de); - g_signal_connect_swapped (de->data_sheet, "activate", + g_signal_connect_swapped (de->data_sheet[0], "activate", G_CALLBACK (on_activate), de); - g_signal_connect_swapped (de->data_sheet, "deactivate", + for (i = 0 ; i < 4 ; ++i ) + g_signal_connect (de->data_sheet[i], "activate", + G_CALLBACK (on_data_sheet_activate), + de); + + g_signal_connect_swapped (de->data_sheet[0], "deactivate", G_CALLBACK (on_deactivate), de); - g_signal_connect_swapped (de->data_sheet, "select-range", + g_signal_connect_swapped (de->data_sheet[0], "select-range", G_CALLBACK (on_select_range), de); - g_signal_connect (de->data_sheet, "select-row", + g_signal_connect (de->data_sheet[0], "select-row", G_CALLBACK (on_select_row), de); - g_signal_connect (de->data_sheet, "select-column", + g_signal_connect (de->data_sheet[0], "select-column", G_CALLBACK (on_select_variable), de); @@ -655,6 +759,12 @@ psppire_data_editor_init (PsppireDataEditor *de) g_signal_connect (de, "map", G_CALLBACK (on_map), NULL); + + + // gtk_sheet_hide_column_titles (de->var_sheet); + // gtk_sheet_hide_row_titles (de->data_sheet); + + de->dispose_has_run = FALSE; } @@ -670,9 +780,72 @@ psppire_data_editor_new (PsppireVarStore *var_store, "data-store", data_store, NULL); + + return widget; } + +static void +psppire_data_editor_remove_split (PsppireDataEditor *de) +{ + if ( !de->split ) return; + de->split = FALSE; + + g_object_ref (de->sheet_bin[0]); + gtk_container_remove (GTK_CONTAINER (de->paned), de->sheet_bin[0]); + + g_object_ref (de->paned); + gtk_container_remove (GTK_CONTAINER (de->data_vbox), de->paned); + + gtk_box_pack_start (GTK_BOX (de->data_vbox), de->sheet_bin[0], + TRUE, TRUE, 0); + + g_object_unref (de->sheet_bin[0]); + + g_object_set (de->sheet_bin[0], "vscrollbar-policy", + GTK_POLICY_ALWAYS, NULL); + + g_object_set (de->sheet_bin[0], "hscrollbar-policy", + GTK_POLICY_ALWAYS, NULL); +} + + +static void +psppire_data_editor_set_split (PsppireDataEditor *de) +{ + if ( de->split ) return; + de->split = TRUE; + + g_object_ref (de->sheet_bin[0]); + gtk_container_remove (GTK_CONTAINER (de->data_vbox), de->sheet_bin[0]); + + gtk_xpaned_pack_top_left (GTK_XPANED (de->paned), de->sheet_bin [0], + TRUE, TRUE); + + gtk_box_pack_start (GTK_BOX (de->data_vbox), de->paned, + TRUE, TRUE, 0); + + g_object_unref (de->paned); + + g_object_set (de->sheet_bin[0], "vscrollbar-policy", + GTK_POLICY_NEVER, NULL); + + g_object_set (de->sheet_bin[0], "hscrollbar-policy", + GTK_POLICY_NEVER, NULL); +} + +void +psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split) +{ + if (split ) + psppire_data_editor_set_split (de); + else + psppire_data_editor_remove_split (de); + + gtk_widget_show_all (de->data_vbox); +} + static void data_sheet_set_clip (GtkSheet *sheet); static void data_sheet_contents_received_callback (GtkClipboard *clipboard, GtkSelectionData *sd, @@ -682,7 +855,7 @@ static void data_sheet_contents_received_callback (GtkClipboard *clipboard, void psppire_data_editor_clip_copy (PsppireDataEditor *de) { - data_sheet_set_clip (GTK_SHEET (de->data_sheet)); + data_sheet_set_clip (GTK_SHEET (de->data_sheet[0])); } void @@ -706,16 +879,16 @@ psppire_data_editor_clip_cut (PsppireDataEditor *de) GtkSheetRange range; PsppireDataStore *ds = de->data_store; - data_sheet_set_clip (GTK_SHEET (de->data_sheet)); + data_sheet_set_clip (GTK_SHEET (de->data_sheet[0])); /* Now blank all the cells */ - gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range); + gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range); /* If nothing selected, then use active cell */ if ( range.row0 < 0 || range.col0 < 0 ) { gint row, col; - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col); range.row0 = range.rowi = row; range.col0 = range.coli = col; @@ -756,7 +929,7 @@ psppire_data_editor_clip_cut (PsppireDataEditor *de) } /* and remove the selection */ - gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet)); + gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0])); } @@ -838,7 +1011,7 @@ void psppire_data_editor_sort_ascending (PsppireDataEditor *de) { GtkSheetRange range; - gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet), &range); + gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet[0]), &range); do_sort (de->data_store, range.col0, FALSE); } @@ -850,7 +1023,7 @@ void psppire_data_editor_sort_descending (PsppireDataEditor *de) { GtkSheetRange range; - gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet), &range); + gtk_sheet_get_selected_range (GTK_SHEET(de->data_sheet[0]), &range); do_sort (de->data_store, range.col0, TRUE); } @@ -865,10 +1038,10 @@ psppire_data_editor_insert_variable (PsppireDataEditor *de) { glong posn = -1; - if ( de->data_sheet->state == GTK_SHEET_COLUMN_SELECTED ) - posn = GTK_SHEET (de->data_sheet)->range.col0; + if ( de->data_sheet[0]->state == GTK_SHEET_COLUMN_SELECTED ) + posn = GTK_SHEET (de->data_sheet[0])->range.col0; else - posn = GTK_SHEET (de->data_sheet)->active_cell.col; + posn = GTK_SHEET (de->data_sheet[0])->active_cell.col; if ( posn == -1 ) posn = 0; @@ -881,10 +1054,10 @@ psppire_data_editor_insert_case (PsppireDataEditor *de) { glong posn = -1; - if ( de->data_sheet->state == GTK_SHEET_ROW_SELECTED ) - posn = GTK_SHEET (de->data_sheet)->range.row0; + if ( de->data_sheet[0]->state == GTK_SHEET_ROW_SELECTED ) + posn = GTK_SHEET (de->data_sheet[0])->range.row0; else - posn = GTK_SHEET (de->data_sheet)->active_cell.row; + posn = GTK_SHEET (de->data_sheet[0])->active_cell.row; if ( posn == -1 ) posn = 0; @@ -895,12 +1068,12 @@ psppire_data_editor_insert_case (PsppireDataEditor *de) void psppire_data_editor_delete_cases (PsppireDataEditor *de) { - gint first = GTK_SHEET (de->data_sheet)->range.row0; - gint n = GTK_SHEET (de->data_sheet)->range.rowi - first + 1; + gint first = GTK_SHEET (de->data_sheet[0])->range.row0; + gint n = GTK_SHEET (de->data_sheet[0])->range.rowi - first + 1; psppire_data_store_delete_cases (de->data_store, first, n); - gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet)); + gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0])); } /* Delete the variables currently selected in the @@ -913,8 +1086,8 @@ psppire_data_editor_delete_variables (PsppireDataEditor *de) switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de))) { case PSPPIRE_DATA_EDITOR_DATA_VIEW: - first = GTK_SHEET (de->data_sheet)->range.col0; - n = GTK_SHEET (de->data_sheet)->range.coli - first + 1; + first = GTK_SHEET (de->data_sheet[0])->range.col0; + n = GTK_SHEET (de->data_sheet[0])->range.coli - first + 1; break; case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW: first = GTK_SHEET (de->var_sheet)->range.row0; @@ -927,7 +1100,7 @@ psppire_data_editor_delete_variables (PsppireDataEditor *de) psppire_dict_delete_variables (de->var_store->dict, first, n); - gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet)); + gtk_sheet_unselect_range (GTK_SHEET (de->data_sheet[0])); gtk_sheet_unselect_range (GTK_SHEET (de->var_sheet)); } @@ -936,7 +1109,7 @@ void psppire_data_editor_show_grid (PsppireDataEditor *de, gboolean grid_visible) { gtk_sheet_show_grid (GTK_SHEET (de->var_sheet), grid_visible); - gtk_sheet_show_grid (GTK_SHEET (de->data_sheet), grid_visible); + gtk_sheet_show_grid (GTK_SHEET (de->data_sheet[0]), grid_visible); } void @@ -958,11 +1131,32 @@ emit_selected_signal (PsppireDataEditor *de) g_signal_emit (de, data_editor_signals[DATA_SELECTION_CHANGED], 0, data_selected); } +static gboolean +on_data_sheet_activate (GtkWidget *sheet, gint row, gint col, PsppireDataEditor *de) +{ + gint i; + + for ( i = 0 ; i < 4 ; ++i ) + { + gint current_row, current_col; + if (de->data_sheet[i] == sheet) continue; + + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), ¤t_row, ¤t_col); + + if ( row == current_row && current_col == col ) continue; + + gtk_sheet_set_active_cell (GTK_SHEET (de->data_sheet[i]), row, col); + } + + return TRUE; +} + static void on_activate (PsppireDataEditor *de) { gint row, col; - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col); + if ( row < psppire_data_store_get_case_count (de->data_store) && @@ -987,7 +1181,7 @@ on_select_range (PsppireDataEditor *de) { GtkSheetRange range; - gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range); + gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range); if ( range.rowi < psppire_data_store_get_case_count (de->data_store) && @@ -1002,7 +1196,8 @@ on_select_range (PsppireDataEditor *de) static gboolean -on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p, gint pagenum, gpointer data) +on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p, + gint pagenum, gpointer data) { if ( pagenum != PSPPIRE_DATA_EDITOR_DATA_VIEW ) { @@ -1026,7 +1221,7 @@ data_is_selected (PsppireDataEditor *de) if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (de)) != PSPPIRE_DATA_EDITOR_DATA_VIEW) return FALSE; - gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet), &row, &col); + gtk_sheet_get_active_cell (GTK_SHEET (de->data_sheet[0]), &row, &col); if ( row >= psppire_data_store_get_case_count (de->data_store) || @@ -1035,7 +1230,7 @@ data_is_selected (PsppireDataEditor *de) return FALSE; } - gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet), &range); + gtk_sheet_get_selected_range (GTK_SHEET (de->data_sheet[0]), &range); if ( range.rowi >= psppire_data_store_get_case_count (de->data_store) || @@ -1375,7 +1570,7 @@ data_sheet_contents_received_callback (GtkClipboard *clipboard, c = (char *) sd->data; /* Paste text to selected position */ - gtk_sheet_get_active_cell (GTK_SHEET (data_editor->data_sheet), + gtk_sheet_get_active_cell (GTK_SHEET (data_editor->data_sheet[0]), &row, &column); g_return_if_fail (row >= 0); @@ -1438,3 +1633,5 @@ on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data) g_signal_emit (de, data_editor_signals[DATA_AVAILABLE_CHANGED], 0, compatible_target); } + + diff --git a/src/ui/gui/psppire-data-editor.h b/src/ui/gui/psppire-data-editor.h index b896c545..7716f52c 100644 --- a/src/ui/gui/psppire-data-editor.h +++ b/src/ui/gui/psppire-data-editor.h @@ -46,10 +46,17 @@ struct _PsppireDataEditor gboolean dispose_has_run; GtkWidget *cell_ref_entry; GtkWidget *datum_entry; - GtkWidget *data_sheet; GtkWidget *var_sheet; PsppireDataStore *data_store; PsppireVarStore *var_store; + + GtkWidget *sheet_bin[4]; + GtkWidget *data_sheet[4]; + + GtkWidget *data_vbox; + + GtkWidget *paned; + gboolean split; }; @@ -73,7 +80,7 @@ void psppire_data_editor_insert_case (PsppireDataEditor *); void psppire_data_editor_delete_cases (PsppireDataEditor *); void psppire_data_editor_set_font (PsppireDataEditor *, PangoFontDescription *); void psppire_data_editor_delete_cases (PsppireDataEditor *); - +void psppire_data_editor_split_window (PsppireDataEditor *, gboolean ); G_END_DECLS diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index afbe3d2f..18aaaeba 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -56,7 +56,6 @@ static gboolean psppire_data_store_clear_datum (GSheetModel *model, #define MIN_COLUMNS 10 - #define TRAILING_ROWS 10 static GObjectClass *parent_class = NULL; @@ -800,9 +799,11 @@ geometry_set_width (GSheetColumn *geom, glong unit, gint width) { PsppireDataStore *ds = PSPPIRE_DATA_STORE (geom); - struct variable *pv = psppire_dict_get_variable (ds->dict, unit); + struct variable *v = psppire_dict_get_variable (ds->dict, unit); + + g_return_if_fail (v); - var_set_display_width (pv, width / ds->width_of_m ); + var_set_display_width (v, width / ds->width_of_m ); } @@ -934,7 +935,6 @@ geometry_get_row_sensitivity (const GSheetRow *geom, glong unit) return (unit < psppire_case_file_get_case_count (ds->case_file)); } - static gchar * geometry_get_row_button_label (const GSheetRow *geom, glong unit) {