1 /* GtkSheet widget for Gtk+.
2 * Copyright (C) 1999-2001 Adrian E. Feiguin <adrian@ifir.ifir.edu.ar>
4 * Based on GtkClist widget by Jay Painter, but major changes.
5 * Memory allocation routines inspired on SC (Spreadsheet Calculator)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
31 #include <glib-object.h>
32 #include <gobject/gvaluecollector.h>
34 #include <gdk/gdkkeysyms.h>
35 #include <gtk/gtksignal.h>
36 #include <gtk/gtklabel.h>
37 #include <gtk/gtkbutton.h>
38 #include <gtk/gtkadjustment.h>
39 #include <gtk/gtktable.h>
40 #include <gtk/gtkbox.h>
41 #include <gtk/gtkmain.h>
42 #include <gtk/gtktypeutils.h>
43 #include <gtk/gtkentry.h>
44 #include <gtk/gtkcontainer.h>
45 #include <gtk/gtkpixmap.h>
46 #include <pango/pango.h>
47 #include "gtkitementry_2_2.h"
48 #include "gtksheet_2_2.h"
49 #include "gtkextra-marshal.h"
51 /*------------------------------------------------------------------
52 * Gattrib specific includes -- stuff dealing with gattrib data structs.
53 * Included here in order to grab sheet_head->CHANGED, which is set
54 * when the user puts a new value in a cell.
55 *------------------------------------------------------------------*/
56 #include <libgeda/libgeda.h> /* geda library fcns */
57 #include "../include/struct.h" /* typdef and struct declarations */
58 #include "../include/prototype.h" /* function prototypes */
59 #include "../include/globals.h"
61 #ifdef HAVE_LIBDMALLOC
69 GTK_SHEET_IS_LOCKED
= 1 << 0,
70 GTK_SHEET_IS_FROZEN
= 1 << 1,
71 GTK_SHEET_IN_XDRAG
= 1 << 2,
72 GTK_SHEET_IN_YDRAG
= 1 << 3,
73 GTK_SHEET_IN_DRAG
= 1 << 4,
74 GTK_SHEET_IN_SELECTION
= 1 << 5,
75 GTK_SHEET_IN_RESIZE
= 1 << 6,
76 GTK_SHEET_IN_CLIP
= 1 << 7,
77 GTK_SHEET_REDRAW_PENDING
= 1 << 8,
80 #define GTK_SHEET_FLAGS(sheet) (GTK_SHEET (sheet)->flags)
81 #define GTK_SHEET_SET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) |= (flag))
82 #define GTK_SHEET_UNSET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) &= ~(flag))
84 #define GTK_SHEET_IS_FROZEN(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN)
85 #define GTK_SHEET_IN_XDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG)
86 #define GTK_SHEET_IN_YDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG)
87 #define GTK_SHEET_IN_DRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_DRAG)
88 #define GTK_SHEET_IN_SELECTION(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_SELECTION)
89 #define GTK_SHEET_IN_RESIZE(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_RESIZE)
90 #define GTK_SHEET_IN_CLIP(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_CLIP)
91 #define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING)
93 #define CELL_SPACING 1
95 #define TIMEOUT_SCROLL 20
96 #define TIMEOUT_FLASH 200
97 #define TIME_INTERVAL 8
98 #define COLUMN_MIN_WIDTH 10
103 #define DEFAULT_COLUMN_WIDTH 80
105 static inline guint
DEFAULT_ROW_HEIGHT(GtkWidget
*widget
)
107 if(!widget
->style
->font_desc
) return 24;
109 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
110 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
111 widget
->style
->font_desc
,
112 pango_context_get_language(context
));
113 guint val
= pango_font_metrics_get_descent(metrics
) +
114 pango_font_metrics_get_ascent(metrics
);
115 pango_font_metrics_unref(metrics
);
116 return PANGO_PIXELS(val
)+2*CELLOFFSET
;
119 static inline guint
DEFAULT_FONT_ASCENT(GtkWidget
*widget
)
121 if(!widget
->style
->font_desc
) return 12;
123 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
124 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
125 widget
->style
->font_desc
,
126 pango_context_get_language(context
));
127 guint val
= pango_font_metrics_get_ascent(metrics
);
128 pango_font_metrics_unref(metrics
);
129 return PANGO_PIXELS(val
);
132 static inline guint
STRING_WIDTH(GtkWidget
*widget
,
133 PangoFontDescription
*font
, const gchar
*text
)
138 layout
= gtk_widget_create_pango_layout (widget
, text
);
139 pango_layout_set_font_description (layout
, font
);
141 pango_layout_get_extents (layout
, NULL
, &rect
);
143 g_object_unref(G_OBJECT(layout
));
144 return PANGO_PIXELS(rect
.width
);
147 static inline guint
DEFAULT_FONT_DESCENT(GtkWidget
*widget
)
149 if(!widget
->style
->font_desc
) return 12;
151 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
152 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
153 widget
->style
->font_desc
,
154 pango_context_get_language(context
));
155 guint val
= pango_font_metrics_get_descent(metrics
);
156 pango_font_metrics_unref(metrics
);
157 return PANGO_PIXELS(val
);
161 /*! \brief gives the top pixel of the given row in context of
162 * the sheet's voffset
166 ROW_TOP_YPIXEL(GtkSheet
*sheet
, gint nrow
)
168 return (sheet
->voffset
+ sheet
->row
[nrow
].top_ypixel
);
172 /*! \brief returns the row index from a y pixel location in the
173 * context of the sheet's voffset
177 ROW_FROM_YPIXEL(GtkSheet
*sheet
, gint y
)
182 if(sheet
->column_titles_visible
) cy
+= sheet
->column_title_area
.height
;
184 for (i
= 0; i
<= sheet
->maxrow
; i
++)
186 if (y
>= cy
&& y
<= (cy
+ sheet
->row
[i
].height
) && sheet
->row
[i
].is_visible
)
188 if(sheet
->row
[i
].is_visible
) cy
+= sheet
->row
[i
].height
;
193 return sheet
->maxrow
;
197 /*! \brief gives the left pixel of the given column in context of
198 * the sheet's hoffset
202 COLUMN_LEFT_XPIXEL(GtkSheet
*sheet
, gint ncol
)
204 return (sheet
->hoffset
+ sheet
->column
[ncol
].left_xpixel
);
207 /*! \brief returns the column index from a x pixel location in the
208 * context of the sheet's hoffset
212 COLUMN_FROM_XPIXEL (GtkSheet
* sheet
,
218 if(sheet
->row_titles_visible
) cx
+= sheet
->row_title_area
.width
;
220 for (i
= 0; i
<= sheet
->maxcol
; i
++)
222 if (x
>= cx
&& x
<= (cx
+ sheet
->column
[i
].width
) && sheet
->column
[i
].is_visible
)
224 if(sheet
->column
[i
].is_visible
) cx
+= sheet
->column
[i
].width
;
229 return sheet
->maxcol
;
232 /*! \brief returns the total height of the sheet
235 static inline gint
SHEET_HEIGHT(GtkSheet
*sheet
)
240 if(sheet
->column_titles_visible
) cx
+= sheet
->column_title_area
.height
;
241 for (i
=0;i
<=sheet
->maxrow
; i
++)
242 if(sheet
->row
[i
].is_visible
) cx
+= sheet
->row
[i
].height
;
248 /*! \brief returns the total width of the sheet
251 static inline gint
SHEET_WIDTH(GtkSheet
*sheet
)
256 if(sheet
->row_titles_visible
) cx
+= sheet
->row_title_area
.width
;
257 for (i
=0;i
<=sheet
->maxcol
; i
++)
258 if(sheet
->column
[i
].is_visible
) cx
+= sheet
->column
[i
].width
;
263 #define MIN_VISIBLE_ROW(sheet) sheet->view.row0
264 #define MAX_VISIBLE_ROW(sheet) sheet->view.rowi
265 #define MIN_VISIBLE_COLUMN(sheet) sheet->view.col0
266 #define MAX_VISIBLE_COLUMN(sheet) sheet->view.coli
270 POSSIBLE_XDRAG(GtkSheet
*sheet
, gint x
, gint
*drag_column
)
274 column
=COLUMN_FROM_XPIXEL(sheet
, x
);
277 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,column
)+CELL_SPACING
;
278 if(x
<= xdrag
+DRAG_WIDTH
/2 && column
!= 0){
279 while(!sheet
->column
[column
-1].is_visible
&& column
>0) column
--;
280 *drag_column
=column
-1;
281 return sheet
->column
[column
-1].is_sensitive
;
284 xdrag
+=sheet
->column
[column
].width
;
285 if(x
>= xdrag
-DRAG_WIDTH
/2 && x
<= xdrag
+DRAG_WIDTH
/2)
286 return sheet
->column
[column
].is_sensitive
;
292 POSSIBLE_YDRAG(GtkSheet
*sheet
, gint y
, gint
*drag_row
)
296 row
=ROW_FROM_YPIXEL(sheet
, y
);
299 ydrag
=ROW_TOP_YPIXEL(sheet
,row
)+CELL_SPACING
;
300 if(y
<= ydrag
+DRAG_WIDTH
/2 && row
!= 0){
301 while(!sheet
->row
[row
-1].is_visible
&& row
>0) row
--;
303 return sheet
->row
[row
-1].is_sensitive
;
306 ydrag
+=sheet
->row
[row
].height
;
308 if(y
>= ydrag
-DRAG_WIDTH
/2 && y
<= ydrag
+DRAG_WIDTH
/2)
309 return sheet
->row
[row
].is_sensitive
;
315 static inline gint
POSSIBLE_DRAG(GtkSheet
*sheet
, gint x
, gint y
,
316 gint
*drag_row
, gint
*drag_column
)
320 *drag_column
=COLUMN_FROM_XPIXEL(sheet
,x
);
321 *drag_row
=ROW_FROM_YPIXEL(sheet
,y
);
323 if(x
>=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.col0
)-DRAG_WIDTH
/2 &&
324 x
<=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
325 sheet
->column
[sheet
->range
.coli
].width
+DRAG_WIDTH
/2){
326 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.row0
);
327 if(y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2){
328 *drag_row
=sheet
->range
.row0
;
331 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
332 sheet
->row
[sheet
->range
.rowi
].height
;
333 if(y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2){
334 *drag_row
=sheet
->range
.rowi
;
339 if(y
>=ROW_TOP_YPIXEL(sheet
,sheet
->range
.row0
)-DRAG_WIDTH
/2 &&
340 y
<=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
341 sheet
->row
[sheet
->range
.rowi
].height
+DRAG_WIDTH
/2){
342 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.col0
);
343 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2){
344 *drag_column
=sheet
->range
.col0
;
347 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
348 sheet
->column
[sheet
->range
.coli
].width
;
349 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2){
350 *drag_column
=sheet
->range
.coli
;
357 static inline gint
POSSIBLE_RESIZE(GtkSheet
*sheet
, gint x
, gint y
,
358 gint
*drag_row
, gint
*drag_column
)
362 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
363 sheet
->column
[sheet
->range
.coli
].width
;
365 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
366 sheet
->row
[sheet
->range
.rowi
].height
;
368 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
369 ydrag
= ROW_TOP_YPIXEL(sheet
, sheet
->view
.row0
);
371 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
372 xdrag
= COLUMN_LEFT_XPIXEL(sheet
, sheet
->view
.col0
);
374 *drag_column
=COLUMN_FROM_XPIXEL(sheet
,x
);
375 *drag_row
=ROW_FROM_YPIXEL(sheet
,y
);
377 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2 &&
378 y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2) return TRUE
;
383 static void gtk_sheet_class_init (GtkSheetClass
* klass
);
384 static void gtk_sheet_init (GtkSheet
* sheet
);
385 static void gtk_sheet_destroy (GtkObject
* object
);
386 static void gtk_sheet_finalize (GObject
* object
);
387 static void gtk_sheet_style_set (GtkWidget
*widget
,
388 GtkStyle
*previous_style
);
389 static void gtk_sheet_realize (GtkWidget
* widget
);
390 static void gtk_sheet_unrealize (GtkWidget
* widget
);
391 static void gtk_sheet_map (GtkWidget
* widget
);
392 static void gtk_sheet_unmap (GtkWidget
* widget
);
393 static gint
gtk_sheet_expose (GtkWidget
* widget
,
394 GdkEventExpose
* event
);
395 static void gtk_sheet_forall (GtkContainer
*container
,
396 gboolean include_internals
,
397 GtkCallback callback
,
398 gpointer callback_data
);
400 static void gtk_sheet_set_scroll_adjustments (GtkSheet
*sheet
,
401 GtkAdjustment
*hadjustment
,
402 GtkAdjustment
*vadjustment
);
404 static gint
gtk_sheet_button_press (GtkWidget
* widget
,
405 GdkEventButton
* event
);
406 static gint
gtk_sheet_button_release (GtkWidget
* widget
,
407 GdkEventButton
* event
);
408 static gint
gtk_sheet_motion (GtkWidget
* widget
,
409 GdkEventMotion
* event
);
412 static gint
gtk_sheet_entry_key_press (GtkWidget
*widget
,
416 static gint
gtk_sheet_key_press (GtkWidget
*widget
,
419 static void gtk_sheet_size_request (GtkWidget
* widget
,
420 GtkRequisition
* requisition
);
421 static void gtk_sheet_size_allocate (GtkWidget
* widget
,
422 GtkAllocation
* allocation
);
426 static gint
gtk_sheet_range_isvisible (GtkSheet
* sheet
,
427 GtkSheetRange range
);
428 static gint
gtk_sheet_cell_isvisible (GtkSheet
* sheet
,
429 gint row
, gint column
);
432 static gint
gtk_sheet_scroll (gpointer data
);
433 static gint
gtk_sheet_flash (gpointer data
);
435 /* Drawing Routines */
437 /* draw cell background and frame */
438 static void gtk_sheet_cell_draw_default (GtkSheet
*sheet
,
439 gint row
, gint column
);
441 /* draw cell border */
442 static void gtk_sheet_cell_draw_border (GtkSheet
*sheet
,
443 gint row
, gint column
,
446 /* draw cell contents */
447 static void gtk_sheet_cell_draw_label (GtkSheet
*sheet
,
448 gint row
, gint column
);
450 /* draw visible part of range. If range==NULL then draw the whole screen */
451 static void gtk_sheet_range_draw (GtkSheet
*sheet
,
452 const GtkSheetRange
*range
);
454 /* highlight the visible part of the selected range */
455 static void gtk_sheet_range_draw_selection (GtkSheet
*sheet
,
456 GtkSheetRange range
);
460 static gint
gtk_sheet_move_query (GtkSheet
*sheet
,
461 gint row
, gint column
);
462 static void gtk_sheet_real_select_range (GtkSheet
* sheet
,
463 GtkSheetRange
* range
);
464 static void gtk_sheet_real_unselect_range (GtkSheet
* sheet
,
465 const GtkSheetRange
* range
);
466 static void gtk_sheet_extend_selection (GtkSheet
*sheet
,
467 gint row
, gint column
);
468 static void gtk_sheet_new_selection (GtkSheet
*sheet
,
469 GtkSheetRange
*range
);
470 static void gtk_sheet_draw_border (GtkSheet
*sheet
,
471 GtkSheetRange range
);
472 static void gtk_sheet_draw_corners (GtkSheet
*sheet
,
473 GtkSheetRange range
);
476 /* Active Cell handling */
478 static void gtk_sheet_entry_changed (GtkWidget
*widget
,
480 static gboolean
gtk_sheet_deactivate_cell (GtkSheet
*sheet
);
481 static void gtk_sheet_hide_active_cell (GtkSheet
*sheet
);
482 static gboolean
gtk_sheet_activate_cell (GtkSheet
*sheet
,
484 static void gtk_sheet_draw_active_cell (GtkSheet
*sheet
);
485 static void gtk_sheet_show_active_cell (GtkSheet
*sheet
);
486 static void gtk_sheet_click_cell (GtkSheet
*sheet
,
493 static void gtk_sheet_make_backing_pixmap (GtkSheet
*sheet
,
494 guint width
, guint height
);
495 static void gtk_sheet_draw_backing_pixmap (GtkSheet
*sheet
,
496 GtkSheetRange range
);
499 static void adjust_scrollbars (GtkSheet
* sheet
);
500 static void vadjustment_changed (GtkAdjustment
* adjustment
,
502 static void hadjustment_changed (GtkAdjustment
* adjustment
,
504 static void vadjustment_value_changed (GtkAdjustment
* adjustment
,
506 static void hadjustment_value_changed (GtkAdjustment
* adjustment
,
510 static void draw_xor_vline (GtkSheet
* sheet
);
511 static void draw_xor_hline (GtkSheet
* sheet
);
512 static void draw_xor_rectangle (GtkSheet
*sheet
,
513 GtkSheetRange range
);
514 static void gtk_sheet_draw_flashing_range (GtkSheet
*sheet
,
515 GtkSheetRange range
);
516 static guint
new_column_width (GtkSheet
* sheet
,
519 static guint
new_row_height (GtkSheet
* sheet
,
524 static void create_global_button (GtkSheet
*sheet
);
525 static void global_button_clicked (GtkWidget
*widget
,
529 static void create_sheet_entry (GtkSheet
*sheet
);
530 static void gtk_sheet_size_allocate_entry (GtkSheet
*sheet
);
531 static void gtk_sheet_entry_set_max_size (GtkSheet
*sheet
);
533 /* Sheet button gadgets */
535 static void size_allocate_column_title_buttons (GtkSheet
* sheet
);
536 static void size_allocate_row_title_buttons (GtkSheet
* sheet
);
537 static void gtk_sheet_recalc_top_ypixels (GtkSheet
*sheet
,
539 static void gtk_sheet_recalc_left_xpixels (GtkSheet
*sheet
,
541 static void row_button_set (GtkSheet
*sheet
,
543 static void column_button_set (GtkSheet
*sheet
,
545 static void row_button_release (GtkSheet
*sheet
,
547 static void column_button_release (GtkSheet
*sheet
,
549 static void gtk_sheet_button_draw (GtkSheet
*sheet
,
550 gint row
, gint column
);
551 static void size_allocate_global_button (GtkSheet
*sheet
);
552 static void gtk_sheet_button_size_request (GtkSheet
*sheet
,
553 GtkSheetButton
*button
,
554 GtkRequisition
*requisition
);
556 /* Attributes routines */
558 static void gtk_sheet_set_cell_attributes (GtkSheet
*sheet
,
560 GtkSheetCellAttr attributes
);
562 static void init_attributes (GtkSheet
*sheet
, gint col
,
563 GtkSheetCellAttr
*attributes
);
564 /* Memory allocation routines */
565 static void gtk_sheet_real_range_clear (GtkSheet
*sheet
,
566 const GtkSheetRange
*range
,
568 static void gtk_sheet_real_cell_clear (GtkSheet
*sheet
,
572 static GtkSheetCell
* gtk_sheet_cell_new (void);
573 static gint
AddRow (GtkSheet
*sheet
, gint nrows
);
574 static gint
AddColumn (GtkSheet
*sheet
, gint ncols
);
575 static gint
InsertRow (GtkSheet
*sheet
, gint row
, gint nrows
);
576 static gint
InsertColumn (GtkSheet
*sheet
, gint col
, gint ncols
);
577 static gint
DeleteRow (GtkSheet
*sheet
, gint row
, gint nrows
);
578 static gint
DeleteColumn (GtkSheet
*sheet
, gint col
, gint ncols
);
579 static gint
GrowSheet (GtkSheet
*sheet
,
580 gint newrows
, gint newcols
);
581 static gint
CheckBounds (GtkSheet
*sheet
,
584 /* Container Functions */
585 static void gtk_sheet_remove (GtkContainer
*container
,
587 static void gtk_sheet_realize_child (GtkSheet
*sheet
,
588 GtkSheetChild
*child
);
589 static void gtk_sheet_position_child (GtkSheet
*sheet
,
590 GtkSheetChild
*child
);
591 static void gtk_sheet_position_children (GtkSheet
*sheet
);
592 static void gtk_sheet_child_show (GtkSheetChild
*child
);
593 static void gtk_sheet_child_hide (GtkSheetChild
*child
);
594 static void gtk_sheet_column_size_request (GtkSheet
*sheet
,
597 static void gtk_sheet_row_size_request (GtkSheet
*sheet
,
604 /* \brief Imported from gtkextra.c by SDB 7.22.2004
608 _gtkextra_signal_emit(GtkObject
*object
, guint signal_id
, ...)
612 GValue instance_and_params
[10] = { {0, }, };
618 va_start (var_args
, signal_id
);
620 g_value_init(instance_and_params
+ 0, GTK_OBJECT_TYPE(object
));
621 g_value_set_instance (instance_and_params
+ 0, G_OBJECT(object
));
623 g_signal_query(signal_id
, &query
);
625 for (i
= 0; i
< query
.n_params
; i
++)
627 gboolean static_scope
= query
.param_types
[i
]&~G_SIGNAL_TYPE_STATIC_SCOPE
;
628 g_value_init(instance_and_params
+ i
+ 1, query
.param_types
[i
]);
631 G_VALUE_COLLECT (instance_and_params
+ i
+ 1,
633 static_scope
? G_VALUE_NOCOPY_CONTENTS
: 0,
638 g_warning ("%s: %s", G_STRLOC
, error
);
641 g_value_unset (instance_and_params
+ i
);
650 g_value_init(&ret
, query
.return_type
);
651 result
= va_arg(var_args
,gboolean
*);
652 g_value_set_boolean(&ret
, *result
);
653 g_signal_emitv(instance_and_params
, signal_id
, 0, &ret
);
654 *result
= g_value_get_boolean(&ret
);
655 g_value_unset (&ret
);
657 for (i
= 0; i
< query
.n_params
; i
++)
658 g_value_unset (instance_and_params
+ 1 + i
);
659 g_value_unset (instance_and_params
+ 0);
683 static GtkContainerClass
*parent_class
= NULL
;
684 static guint sheet_signals
[LAST_SIGNAL
] = {0};
688 gtk_sheet_get_type ()
690 static GType sheet_type
= 0;
694 static const GTypeInfo sheet_info
=
696 sizeof (GtkSheetClass
),
699 (GClassInitFunc
) gtk_sheet_class_init
,
704 (GInstanceInitFunc
) gtk_sheet_init
,
708 g_type_register_static (GTK_TYPE_CONTAINER
, "GtkSheet",
714 static GtkSheetRange
*
715 gtk_sheet_range_copy (const GtkSheetRange
*range
)
717 GtkSheetRange
*new_range
;
719 g_return_val_if_fail (range
!= NULL
, NULL
);
721 new_range
= g_new (GtkSheetRange
, 1);
729 gtk_sheet_range_free (GtkSheetRange
*range
)
731 g_return_if_fail (range
!= NULL
);
737 gtk_sheet_range_get_type (void)
739 static GType sheet_range_type
;
741 if(!sheet_range_type
)
743 sheet_range_type
= g_boxed_type_register_static("GtkSheetRange", (GBoxedCopyFunc
)gtk_sheet_range_copy
, (GBoxedFreeFunc
)gtk_sheet_range_free
);
745 return sheet_range_type
;
750 gtk_sheet_class_init (GtkSheetClass
* klass
)
752 GtkObjectClass
*object_class
;
753 GtkWidgetClass
*widget_class
;
754 GtkContainerClass
*container_class
;
755 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
757 object_class
= (GtkObjectClass
*) klass
;
758 widget_class
= (GtkWidgetClass
*) klass
;
759 container_class
= (GtkContainerClass
*) klass
;
761 parent_class
= g_type_class_peek_parent (klass
);
763 sheet_signals
[SELECT_ROW
] =
764 gtk_signal_new ("select_row",
766 GTK_CLASS_TYPE(object_class
),
767 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_row
),
769 GTK_TYPE_NONE
, 1, GTK_TYPE_INT
);
771 sheet_signals
[SELECT_COLUMN
] =
772 gtk_signal_new ("select_column",
774 GTK_CLASS_TYPE(object_class
),
775 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_column
),
777 GTK_TYPE_NONE
, 1, GTK_TYPE_INT
);
779 sheet_signals
[SELECT_RANGE
] =
780 gtk_signal_new ("select_range",
782 GTK_CLASS_TYPE(object_class
),
783 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_range
),
784 gtkextra_VOID__BOXED
,
785 GTK_TYPE_NONE
, 1, GTK_TYPE_SHEET_RANGE
);
787 sheet_signals
[CLIP_RANGE
] =
788 gtk_signal_new ("clip_range",
790 GTK_CLASS_TYPE(object_class
),
791 GTK_SIGNAL_OFFSET (GtkSheetClass
, clip_range
),
792 gtkextra_VOID__BOXED
,
793 GTK_TYPE_NONE
, 1, GTK_TYPE_SHEET_RANGE
);
795 sheet_signals
[RESIZE_RANGE
] =
796 gtk_signal_new ("resize_range",
798 GTK_CLASS_TYPE(object_class
),
799 GTK_SIGNAL_OFFSET (GtkSheetClass
, resize_range
),
800 gtkextra_VOID__BOXED_BOXED
,
801 GTK_TYPE_NONE
, 2, GTK_TYPE_SHEET_RANGE
, GTK_TYPE_SHEET_RANGE
);
802 sheet_signals
[MOVE_RANGE
] =
803 gtk_signal_new ("move_range",
805 GTK_CLASS_TYPE(object_class
),
806 GTK_SIGNAL_OFFSET (GtkSheetClass
, move_range
),
807 gtkextra_VOID__BOXED_BOXED
,
808 GTK_TYPE_NONE
, 2, GTK_TYPE_SHEET_RANGE
, GTK_TYPE_SHEET_RANGE
);
809 sheet_signals
[TRAVERSE
] =
810 gtk_signal_new ("traverse",
812 GTK_CLASS_TYPE(object_class
),
813 GTK_SIGNAL_OFFSET (GtkSheetClass
, traverse
),
814 gtkextra_BOOLEAN__INT_INT_POINTER_POINTER
,
815 GTK_TYPE_BOOL
, 4, GTK_TYPE_INT
, GTK_TYPE_INT
,
816 GTK_TYPE_POINTER
, GTK_TYPE_POINTER
);
818 sheet_signals
[DEACTIVATE
] =
819 gtk_signal_new ("deactivate",
821 GTK_CLASS_TYPE(object_class
),
822 GTK_SIGNAL_OFFSET (GtkSheetClass
, deactivate
),
823 gtkextra_BOOLEAN__INT_INT
,
824 GTK_TYPE_BOOL
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
826 sheet_signals
[ACTIVATE
] =
827 gtk_signal_new ("activate",
829 GTK_CLASS_TYPE(object_class
),
830 GTK_SIGNAL_OFFSET (GtkSheetClass
, activate
),
831 gtkextra_BOOLEAN__INT_INT
,
832 GTK_TYPE_BOOL
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
834 sheet_signals
[SET_CELL
] =
835 gtk_signal_new ("set_cell",
837 GTK_CLASS_TYPE(object_class
),
838 GTK_SIGNAL_OFFSET (GtkSheetClass
, set_cell
),
839 gtkextra_VOID__INT_INT
,
840 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
842 sheet_signals
[CLEAR_CELL
] =
843 gtk_signal_new ("clear_cell",
845 GTK_CLASS_TYPE(object_class
),
846 GTK_SIGNAL_OFFSET (GtkSheetClass
, clear_cell
),
847 gtkextra_VOID__INT_INT
,
848 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
850 sheet_signals
[CHANGED
] =
851 gtk_signal_new ("changed",
853 GTK_CLASS_TYPE(object_class
),
854 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
855 gtkextra_VOID__INT_INT
,
856 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
858 sheet_signals
[NEW_COL_WIDTH
] =
859 gtk_signal_new ("new_column_width",
861 GTK_CLASS_TYPE(object_class
),
862 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
863 gtkextra_VOID__INT_INT
,
864 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
866 sheet_signals
[NEW_ROW_HEIGHT
] =
867 gtk_signal_new ("new_row_height",
869 GTK_CLASS_TYPE(object_class
),
870 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
871 gtkextra_VOID__INT_INT
,
872 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
876 widget_class
->set_scroll_adjustments_signal
=
877 gtk_signal_new ("set_scroll_adjustments",
879 GTK_CLASS_TYPE(object_class
),
880 GTK_SIGNAL_OFFSET (GtkSheetClass
, set_scroll_adjustments
),
881 gtkextra_VOID__OBJECT_OBJECT
,
882 GTK_TYPE_NONE
, 2, GTK_TYPE_ADJUSTMENT
, GTK_TYPE_ADJUSTMENT
);
885 container_class
->add
= NULL
;
886 container_class
->remove
= gtk_sheet_remove
;
887 container_class
->forall
= gtk_sheet_forall
;
889 object_class
->destroy
= gtk_sheet_destroy
;
890 gobject_class
->finalize
= gtk_sheet_finalize
;
892 widget_class
->realize
= gtk_sheet_realize
;
893 widget_class
->unrealize
= gtk_sheet_unrealize
;
894 widget_class
->map
= gtk_sheet_map
;
895 widget_class
->unmap
= gtk_sheet_unmap
;
896 widget_class
->style_set
= gtk_sheet_style_set
;
897 widget_class
->button_press_event
= gtk_sheet_button_press
;
898 widget_class
->button_release_event
= gtk_sheet_button_release
;
899 widget_class
->motion_notify_event
= gtk_sheet_motion
;
900 widget_class
->key_press_event
= gtk_sheet_key_press
;
901 widget_class
->expose_event
= gtk_sheet_expose
;
902 widget_class
->size_request
= gtk_sheet_size_request
;
903 widget_class
->size_allocate
= gtk_sheet_size_allocate
;
904 widget_class
->focus_in_event
= NULL
;
905 widget_class
->focus_out_event
= NULL
;
907 klass
->set_scroll_adjustments
= gtk_sheet_set_scroll_adjustments
;
908 klass
->select_row
= NULL
;
909 klass
->select_column
= NULL
;
910 klass
->select_range
= NULL
;
911 klass
->clip_range
= NULL
;
912 klass
->resize_range
= NULL
;
913 klass
->move_range
= NULL
;
914 klass
->traverse
= NULL
;
915 klass
->deactivate
= NULL
;
916 klass
->activate
= NULL
;
917 klass
->set_cell
= NULL
;
918 klass
->clear_cell
= NULL
;
919 klass
->changed
= NULL
;
921 gtk_widget_class_install_style_property (widget_class
,
922 g_param_spec_boxed ("default-border",
923 NULL
, /* P_("Default Spacing"),*/
924 NULL
, /* P_("Extra space to add for CAN_DEFAULT buttons"), */
928 gtk_widget_class_install_style_property (widget_class
,
929 g_param_spec_boxed ("default-outside-border",
930 NULL
, /* P_("Default Outside Spacing"), */
931 NULL
, /* P_("Extra space to add for CAN_DEFAULT buttons that is always drawn outside the border"), */
937 gtk_sheet_init (GtkSheet
*sheet
)
939 sheet
->children
= NULL
;
942 sheet
->selection_mode
= GTK_SELECTION_BROWSE
;
943 sheet
->freeze_count
= 0;
944 sheet
->state
= GTK_SHEET_NORMAL
;
946 GTK_WIDGET_UNSET_FLAGS (sheet
, GTK_NO_WINDOW
);
947 GTK_WIDGET_SET_FLAGS (sheet
, GTK_CAN_FOCUS
);
952 sheet
->view
.row0
= 0;
953 sheet
->view
.col0
= 0;
954 sheet
->view
.rowi
= 0;
955 sheet
->view
.coli
= 0;
957 sheet
->maxallocrow
= 0;
958 sheet
->maxalloccol
= 0;
960 sheet
->column_title_window
=NULL
;
961 sheet
->column_title_area
.x
=0;
962 sheet
->column_title_area
.y
=0;
963 sheet
->column_title_area
.width
=0;
964 sheet
->column_title_area
.height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
966 sheet
->row_title_window
=NULL
;
967 sheet
->row_title_area
.x
=0;
968 sheet
->row_title_area
.y
=0;
969 sheet
->row_title_area
.width
=DEFAULT_COLUMN_WIDTH
;
970 sheet
->row_title_area
.height
=0;
972 sheet
->active_cell
.row
=0;
973 sheet
->active_cell
.col
=0;
974 sheet
->selection_cell
.row
=0;
975 sheet
->selection_cell
.col
=0;
977 sheet
->sheet_entry
=NULL
;
985 sheet
->state
=GTK_SHEET_NORMAL
;
987 sheet
->sheet_window
= NULL
;
988 sheet
->sheet_window_width
= 0;
989 sheet
->sheet_window_height
= 0;
990 sheet
->sheet_entry
= NULL
;
991 sheet
->button
= NULL
;
996 sheet
->hadjustment
= NULL
;
997 sheet
->vadjustment
= NULL
;
999 sheet
->cursor_drag
= gdk_cursor_new(GDK_PLUS
);
1000 sheet
->xor_gc
= NULL
;
1001 sheet
->fg_gc
= NULL
;
1002 sheet
->bg_gc
= NULL
;
1006 gdk_color_white(gdk_colormap_get_system(), &sheet
->bg_color
);
1007 gdk_color_parse("gray", &sheet
->grid_color
);
1008 gdk_color_alloc(gdk_colormap_get_system(), &sheet
->grid_color
);
1009 sheet
->show_grid
= TRUE
;
1013 gtk_sheet_new (guint rows
, guint columns
, const gchar
*title
)
1018 g_return_val_if_fail (columns
>= MINCOLS
, NULL
);
1019 g_return_val_if_fail (rows
>= MINROWS
, NULL
);
1021 widget
= gtk_type_new (gtk_sheet_get_type ());
1023 gtk_sheet_construct(GTK_SHEET(widget
), rows
, columns
, title
);
1029 gtk_sheet_construct (GtkSheet
*sheet
, guint rows
, guint columns
, const gchar
*title
)
1031 sheet
->row
=(GtkSheetRow
*)g_malloc(sizeof(GtkSheetRow
));
1032 sheet
->column
=(GtkSheetColumn
*)g_malloc(sizeof(GtkSheetColumn
));
1033 sheet
->data
=(GtkSheetCell
***)g_malloc(sizeof(GtkSheetCell
**));
1035 sheet
->data
[0] = (GtkSheetCell
**)g_malloc(sizeof(GtkSheetCell
*)+sizeof(gdouble
));
1036 sheet
->data
[0][0] = NULL
;
1038 sheet
->columns_resizable
= TRUE
;
1039 sheet
->rows_resizable
= TRUE
;
1040 sheet
->row_titles_visible
= TRUE
;
1041 sheet
->column_titles_visible
= TRUE
;
1042 sheet
->autoscroll
= TRUE
;
1043 sheet
->justify_entry
= TRUE
;
1044 sheet
->locked
= FALSE
;
1046 /* set number of rows and columns */
1047 GrowSheet(sheet
, MINROWS
, MINCOLS
);
1049 /* Init row an column zero */
1051 AddColumn(sheet
,-1);
1053 /* Add rows and columns */
1054 AddRow(sheet
,rows
-1);
1055 AddColumn(sheet
,columns
-1);
1057 /* create sheet entry */
1058 sheet
->entry_type
= 0;
1059 create_sheet_entry (sheet
);
1061 /* create global selection button */
1062 create_global_button(sheet
);
1065 sheet
->name
= g_strdup(title
);
1071 gtk_sheet_new_browser(guint rows
, guint columns
, const gchar
*title
)
1075 widget
= gtk_type_new (gtk_sheet_get_type ());
1077 gtk_sheet_construct_browser(GTK_SHEET(widget
), rows
, columns
, title
);
1083 gtk_sheet_construct_browser(GtkSheet
*sheet
, guint rows
, guint columns
,
1086 gtk_sheet_construct(sheet
, rows
, columns
, title
);
1088 gtk_sheet_set_locked(sheet
, TRUE
);
1089 sheet
->autoresize
= TRUE
;
1093 gtk_sheet_new_with_custom_entry (guint rows
, guint columns
, const gchar
*title
,
1098 widget
= gtk_type_new (gtk_sheet_get_type ());
1100 gtk_sheet_construct_with_custom_entry(GTK_SHEET(widget
),
1101 rows
, columns
, title
, entry_type
);
1107 gtk_sheet_construct_with_custom_entry (GtkSheet
*sheet
,
1108 guint rows
, guint columns
,
1112 gtk_sheet_construct(sheet
, rows
, columns
, title
);
1114 sheet
->entry_type
= entry_type
;
1115 create_sheet_entry(sheet
);
1120 gtk_sheet_change_entry(GtkSheet
*sheet
, GtkType entry_type
)
1124 g_return_if_fail (sheet
!= NULL
);
1125 g_return_if_fail (GTK_IS_SHEET (sheet
));
1127 state
= sheet
->state
;
1129 if(sheet
->state
== GTK_SHEET_NORMAL
)
1130 gtk_sheet_hide_active_cell(sheet
);
1132 sheet
->entry_type
= entry_type
;
1134 create_sheet_entry(sheet
);
1136 if(state
== GTK_SHEET_NORMAL
)
1138 gtk_sheet_show_active_cell(sheet
);
1139 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
1141 (GtkSignalFunc
)gtk_sheet_entry_changed
,
1142 GTK_OBJECT(GTK_WIDGET(sheet
)));
1148 gtk_sheet_show_grid(GtkSheet
*sheet
, gboolean show
)
1150 g_return_if_fail (sheet
!= NULL
);
1151 g_return_if_fail (GTK_IS_SHEET (sheet
));
1153 if(show
== sheet
->show_grid
) return;
1155 sheet
->show_grid
= show
;
1157 if(!GTK_SHEET_IS_FROZEN(sheet
))
1158 gtk_sheet_range_draw(sheet
, NULL
);
1162 gtk_sheet_grid_visible(GtkSheet
*sheet
)
1164 g_return_val_if_fail (sheet
!= NULL
, 0);
1165 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1167 return sheet
->show_grid
;
1171 gtk_sheet_set_background(GtkSheet
*sheet
, GdkColor
*color
)
1173 g_return_if_fail (sheet
!= NULL
);
1174 g_return_if_fail (GTK_IS_SHEET (sheet
));
1177 gdk_color_white(gdk_colormap_get_system(), &sheet
->bg_color
);
1179 sheet
->bg_color
= *color
;
1181 if(!GTK_SHEET_IS_FROZEN(sheet
))
1182 gtk_sheet_range_draw(sheet
, NULL
);
1186 gtk_sheet_set_grid(GtkSheet
*sheet
, GdkColor
*color
)
1188 g_return_if_fail (sheet
!= NULL
);
1189 g_return_if_fail (GTK_IS_SHEET (sheet
));
1192 gdk_color_black(gdk_colormap_get_system(), &sheet
->grid_color
);
1194 sheet
->grid_color
= *color
;
1196 if(!GTK_SHEET_IS_FROZEN(sheet
))
1197 gtk_sheet_range_draw(sheet
, NULL
);
1201 gtk_sheet_get_columns_count(GtkSheet
*sheet
)
1203 g_return_val_if_fail (sheet
!= NULL
, 0);
1204 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1206 return sheet
->maxcol
+ 1;
1210 gtk_sheet_get_rows_count(GtkSheet
*sheet
)
1212 g_return_val_if_fail (sheet
!= NULL
, 0);
1213 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1215 return sheet
->maxrow
+ 1;
1219 gtk_sheet_get_state(GtkSheet
*sheet
)
1221 g_return_val_if_fail (sheet
!= NULL
, 0);
1222 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1224 return (sheet
->state
);
1228 gtk_sheet_set_selection_mode(GtkSheet
*sheet
, gint mode
)
1230 g_return_if_fail (sheet
!= NULL
);
1231 g_return_if_fail (GTK_IS_SHEET (sheet
));
1233 if(GTK_WIDGET_REALIZED(sheet
))
1234 gtk_sheet_real_unselect_range(sheet
, NULL
);
1236 sheet
->selection_mode
= mode
;
1240 gtk_sheet_set_autoresize (GtkSheet
*sheet
, gboolean autoresize
)
1242 g_return_if_fail (sheet
!= NULL
);
1243 g_return_if_fail (GTK_IS_SHEET (sheet
));
1245 sheet
->autoresize
= autoresize
;
1249 gtk_sheet_autoresize (GtkSheet
*sheet
)
1251 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1252 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1254 return sheet
->autoresize
;
1258 gtk_sheet_set_autoscroll (GtkSheet
*sheet
, gboolean autoscroll
)
1260 g_return_if_fail (sheet
!= NULL
);
1261 g_return_if_fail (GTK_IS_SHEET (sheet
));
1263 sheet
->autoscroll
= autoscroll
;
1267 gtk_sheet_autoscroll (GtkSheet
*sheet
)
1269 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1270 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1272 return sheet
->autoscroll
;
1276 gtk_sheet_set_clip_text (GtkSheet
*sheet
, gboolean clip_text
)
1278 g_return_if_fail (sheet
!= NULL
);
1279 g_return_if_fail (GTK_IS_SHEET (sheet
));
1281 sheet
->clip_text
= clip_text
;
1285 gtk_sheet_clip_text (GtkSheet
*sheet
)
1287 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1288 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1290 return sheet
->clip_text
;
1294 gtk_sheet_set_justify_entry (GtkSheet
*sheet
, gboolean justify
)
1296 g_return_if_fail (sheet
!= NULL
);
1297 g_return_if_fail (GTK_IS_SHEET (sheet
));
1299 sheet
->justify_entry
= justify
;
1303 gtk_sheet_justify_entry (GtkSheet
*sheet
)
1305 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1306 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1308 return sheet
->justify_entry
;
1312 gtk_sheet_set_locked (GtkSheet
*sheet
, gboolean locked
)
1314 g_return_if_fail (sheet
!= NULL
);
1315 g_return_if_fail (GTK_IS_SHEET (sheet
));
1317 sheet
->locked
= locked
;
1321 gtk_sheet_locked (GtkSheet
*sheet
)
1323 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1324 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1326 return sheet
->locked
;
1329 /* This routine has problems with gtk+-1.2 related with the
1330 * label/button drawing - I think it's a bug in gtk+-1.2 */
1333 gtk_sheet_set_title(GtkSheet
*sheet
, const gchar
*title
)
1335 /* GtkWidget *old_widget;
1336 */ GtkWidget
*label
;
1338 g_return_if_fail (sheet
!= NULL
);
1339 g_return_if_fail (title
!= NULL
);
1340 g_return_if_fail (GTK_IS_SHEET (sheet
));
1343 g_free (sheet
->name
);
1345 sheet
->name
= g_strdup (title
);
1347 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) || !title
) return;
1349 if(GTK_BIN(sheet
->button
)->child
)
1350 label
= GTK_BIN(sheet
->button
)->child
;
1352 gtk_label_set_text(GTK_LABEL(label), title);
1354 size_allocate_global_button(sheet
);
1356 /* remove and destroy the old widget */
1358 old_widget = GTK_BIN (sheet->button)->child;
1361 gtk_container_remove (GTK_CONTAINER (sheet->button), old_widget);
1364 label = gtk_label_new (title);
1365 gtk_misc_set_alignment(GTK_MISC(label), 0.5 , 0.5 );
1367 gtk_container_add (GTK_CONTAINER (sheet->button), label);
1368 gtk_widget_show (label);
1370 size_allocate_global_button(sheet);
1372 gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], -1, -1);
1375 gtk_widget_destroy (old_widget);
1380 gtk_sheet_freeze (GtkSheet
*sheet
)
1382 g_return_if_fail (sheet
!= NULL
);
1383 g_return_if_fail (GTK_IS_SHEET (sheet
));
1385 sheet
->freeze_count
++;
1386 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
1390 gtk_sheet_thaw(GtkSheet
*sheet
)
1392 g_return_if_fail (sheet
!= NULL
);
1393 g_return_if_fail (GTK_IS_SHEET (sheet
));
1395 if(sheet
->freeze_count
== 0) return;
1397 sheet
->freeze_count
--;
1398 if(sheet
->freeze_count
> 0) return;
1400 adjust_scrollbars(sheet
);
1402 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
1404 sheet
->old_vadjustment
= -1.;
1405 sheet
->old_hadjustment
= -1.;
1407 if(sheet
->hadjustment
)
1408 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1410 if(sheet
->vadjustment
)
1411 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1414 if(sheet
->state
== GTK_STATE_NORMAL
)
1415 if(sheet
->sheet_entry
&& GTK_WIDGET_MAPPED(sheet
->sheet_entry
)){
1416 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
);
1418 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet)),
1420 (GtkSignalFunc)gtk_sheet_entry_changed,
1421 GTK_OBJECT(GTK_WIDGET(sheet)));
1422 gtk_sheet_show_active_cell(sheet);
1429 gtk_sheet_set_row_titles_width(GtkSheet
*sheet
, guint width
)
1431 if(width
< COLUMN_MIN_WIDTH
) return;
1433 sheet
->row_title_area
.width
= width
;
1434 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
1435 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
1436 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1437 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1438 adjust_scrollbars(sheet
);
1440 sheet
->old_hadjustment
= -1.;
1441 if(sheet
->hadjustment
)
1442 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1444 size_allocate_global_button(sheet
);
1448 gtk_sheet_set_column_titles_height(GtkSheet
*sheet
, guint height
)
1450 if(height
< DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))) return;
1452 sheet
->column_title_area
.height
= height
;
1453 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
1454 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
1455 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1456 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1457 adjust_scrollbars(sheet
);
1459 sheet
->old_vadjustment
= -1.;
1460 if(sheet
->vadjustment
)
1461 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1463 size_allocate_global_button(sheet
);
1467 gtk_sheet_show_column_titles(GtkSheet
*sheet
)
1471 if(sheet
->column_titles_visible
) return;
1473 sheet
->column_titles_visible
= TRUE
;
1474 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1475 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1476 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1477 gdk_window_show(sheet
->column_title_window
);
1478 gdk_window_move_resize (sheet
->column_title_window
,
1479 sheet
->column_title_area
.x
,
1480 sheet
->column_title_area
.y
,
1481 sheet
->column_title_area
.width
,
1482 sheet
->column_title_area
.height
);
1484 for(col
= MIN_VISIBLE_COLUMN(sheet
); col
<= MAX_VISIBLE_COLUMN(sheet
); col
++){
1485 GtkSheetChild
*child
;
1486 child
= sheet
->column
[col
].button
.child
;
1488 gtk_sheet_child_show(child
);
1491 adjust_scrollbars(sheet
);
1494 sheet
->old_vadjustment
= -1.;
1495 if(sheet
->vadjustment
)
1496 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1498 size_allocate_global_button(sheet
);
1502 gtk_sheet_show_row_titles(GtkSheet
*sheet
)
1506 if(sheet
->row_titles_visible
) return;
1508 sheet
->row_titles_visible
= TRUE
;
1509 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1510 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1511 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1512 gdk_window_show(sheet
->row_title_window
);
1513 gdk_window_move_resize (sheet
->row_title_window
,
1514 sheet
->row_title_area
.x
,
1515 sheet
->row_title_area
.y
,
1516 sheet
->row_title_area
.width
,
1517 sheet
->row_title_area
.height
);
1519 for(row
= MIN_VISIBLE_ROW(sheet
); row
<= MAX_VISIBLE_ROW(sheet
); row
++){
1520 GtkSheetChild
*child
;
1521 child
= sheet
->row
[row
].button
.child
;
1523 gtk_sheet_child_show(child
);
1526 adjust_scrollbars(sheet
);
1529 sheet
->old_hadjustment
= -1.;
1530 if(sheet
->hadjustment
)
1531 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1533 size_allocate_global_button(sheet
);
1537 gtk_sheet_hide_column_titles(GtkSheet
*sheet
)
1541 if(!sheet
->column_titles_visible
) return;
1543 sheet
->column_titles_visible
= FALSE
;
1544 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1545 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1546 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1547 if(sheet
->column_title_window
)
1548 gdk_window_hide(sheet
->column_title_window
);
1549 if(GTK_WIDGET_VISIBLE(sheet
->button
))
1550 gtk_widget_hide(sheet
->button
);
1552 for(col
= MIN_VISIBLE_COLUMN(sheet
); col
<= MAX_VISIBLE_COLUMN(sheet
); col
++){
1553 GtkSheetChild
*child
;
1554 child
= sheet
->column
[col
].button
.child
;
1556 gtk_sheet_child_hide(child
);
1559 adjust_scrollbars(sheet
);
1562 sheet
->old_vadjustment
= -1.;
1563 if(sheet
->vadjustment
)
1564 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1569 gtk_sheet_hide_row_titles(GtkSheet
*sheet
)
1573 if(!sheet
->row_titles_visible
) return;
1575 sheet
->row_titles_visible
= FALSE
;
1576 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1577 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1578 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1579 if(sheet
->row_title_window
)
1580 gdk_window_hide(sheet
->row_title_window
);
1581 if(GTK_WIDGET_VISIBLE(sheet
->button
))
1582 gtk_widget_hide(sheet
->button
);
1583 for(row
= MIN_VISIBLE_ROW(sheet
); row
<= MAX_VISIBLE_ROW(sheet
); row
++){
1584 GtkSheetChild
*child
;
1585 child
= sheet
->row
[row
].button
.child
;
1587 gtk_sheet_child_hide(child
);
1590 adjust_scrollbars(sheet
);
1593 sheet
->old_hadjustment
= -1.;
1594 if(sheet
->hadjustment
)
1595 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1600 gtk_sheet_column_titles_visible(GtkSheet
*sheet
)
1602 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1603 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1604 return sheet
->column_titles_visible
;
1608 gtk_sheet_row_titles_visible(GtkSheet
*sheet
)
1610 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1611 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1612 return sheet
->row_titles_visible
;
1616 gtk_sheet_set_column_title (GtkSheet
* sheet
,
1618 const gchar
* title
)
1620 g_return_if_fail (sheet
!= NULL
);
1621 g_return_if_fail (GTK_IS_SHEET (sheet
));
1623 if (sheet
->column
[column
].name
)
1624 g_free (sheet
->column
[column
].name
);
1626 sheet
->column
[column
].name
= g_strdup(title
);
1630 gtk_sheet_set_row_title (GtkSheet
* sheet
,
1632 const gchar
* title
)
1634 g_return_if_fail (sheet
!= NULL
);
1635 g_return_if_fail (GTK_IS_SHEET (sheet
));
1637 if (sheet
->row
[row
].name
)
1638 g_free (sheet
->row
[row
].name
);
1640 sheet
->row
[row
].name
= g_strdup (title
);
1644 gtk_sheet_get_row_title (GtkSheet
* sheet
,
1647 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1648 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1650 return(sheet
->row
[row
].name
);
1654 gtk_sheet_get_column_title (GtkSheet
* sheet
,
1657 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1658 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1660 return(sheet
->column
[column
].name
);
1664 gtk_sheet_row_button_add_label(GtkSheet
*sheet
, gint row
, const gchar
*label
)
1666 GtkSheetButton
*button
;
1670 g_return_if_fail (sheet
!= NULL
);
1671 g_return_if_fail (GTK_IS_SHEET (sheet
));
1673 if(row
< 0 || row
> sheet
->maxrow
) return;
1675 button
= &sheet
->row
[row
].button
;
1676 if (button
->label
) g_free (button
->label
);
1677 button
->label
= g_strdup (label
);
1679 aux
= gtk_sheet_autoresize(sheet
);
1680 gtk_sheet_set_autoresize(sheet
, TRUE
);
1681 gtk_sheet_button_size_request(sheet
, button
, &req
);
1682 gtk_sheet_set_autoresize(sheet
, aux
);
1684 if(req
.height
> sheet
->row
[row
].height
)
1685 gtk_sheet_set_row_height(sheet
, row
, req
.height
);
1687 if(req
.width
> sheet
->row_title_area
.width
){
1688 gtk_sheet_set_row_titles_width(sheet
, req
.width
);
1691 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1692 gtk_sheet_button_draw(sheet
, row
, -1);
1693 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1698 gtk_sheet_row_button_get_label(GtkSheet
*sheet
, gint row
)
1700 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1701 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1703 if(row
< 0 || row
> sheet
->maxrow
) return NULL
;
1705 return (sheet
->row
[row
].button
.label
);
1709 gtk_sheet_row_label_set_visibility(GtkSheet
*sheet
, gint row
, gboolean visible
)
1711 g_return_if_fail (sheet
!= NULL
);
1712 g_return_if_fail (GTK_IS_SHEET (sheet
));
1714 if(row
< 0 || row
> sheet
->maxrow
) return;
1716 sheet
->row
[row
].button
.label_visible
= visible
;
1718 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1719 gtk_sheet_button_draw(sheet
, row
, -1);
1720 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1725 gtk_sheet_rows_labels_set_visibility(GtkSheet
*sheet
, gboolean visible
)
1729 g_return_if_fail (sheet
!= NULL
);
1730 g_return_if_fail (GTK_IS_SHEET (sheet
));
1732 for(i
= 0; i
<= sheet
->maxrow
; i
++)
1733 gtk_sheet_row_label_set_visibility(sheet
, i
, visible
);
1738 gtk_sheet_column_button_add_label(GtkSheet
*sheet
, gint column
, const gchar
*label
)
1740 GtkSheetButton
*button
;
1744 g_return_if_fail (sheet
!= NULL
);
1745 g_return_if_fail (GTK_IS_SHEET (sheet
));
1747 if(column
< 0 || column
>sheet
->maxcol
) return;
1749 button
= &sheet
->column
[column
].button
;
1750 if (button
->label
) g_free (button
->label
);
1751 button
->label
= g_strdup (label
);
1753 aux
= gtk_sheet_autoresize(sheet
);
1754 gtk_sheet_set_autoresize(sheet
, TRUE
);
1755 gtk_sheet_button_size_request(sheet
, button
, &req
);
1756 gtk_sheet_set_autoresize(sheet
, aux
);
1758 if(req
.width
> sheet
->column
[column
].width
)
1759 gtk_sheet_set_column_width(sheet
, column
, req
.width
);
1761 if(req
.height
> sheet
->column_title_area
.height
)
1762 gtk_sheet_set_column_titles_height(sheet
, req
.height
);
1764 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1765 gtk_sheet_button_draw(sheet
, -1, column
);
1766 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, column
);
1771 gtk_sheet_column_button_get_label(GtkSheet
*sheet
, gint column
)
1773 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1774 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1776 if(column
< 0 || column
>sheet
->maxcol
) return NULL
;
1778 return(sheet
->column
[column
].button
.label
);
1782 gtk_sheet_column_label_set_visibility(GtkSheet
*sheet
, gint col
, gboolean visible
)
1784 g_return_if_fail (sheet
!= NULL
);
1785 g_return_if_fail (GTK_IS_SHEET (sheet
));
1787 if(col
< 0 || col
> sheet
->maxcol
) return;
1789 sheet
->column
[col
].button
.label_visible
= visible
;
1791 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1792 gtk_sheet_button_draw(sheet
, -1, col
);
1793 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, col
);
1798 gtk_sheet_columns_labels_set_visibility(GtkSheet
*sheet
, gboolean visible
)
1802 g_return_if_fail (sheet
!= NULL
);
1803 g_return_if_fail (GTK_IS_SHEET (sheet
));
1805 for(i
= 0; i
<= sheet
->maxcol
; i
++)
1806 gtk_sheet_column_label_set_visibility(sheet
, i
, visible
);
1810 gtk_sheet_row_button_justify(GtkSheet
*sheet
, gint row
,
1811 GtkJustification justification
)
1813 GtkSheetButton
*button
;
1815 g_return_if_fail (sheet
!= NULL
);
1816 g_return_if_fail (GTK_IS_SHEET (sheet
));
1818 if(row
< 0 || row
> sheet
->maxrow
) return;
1820 button
= &sheet
->row
[row
].button
;
1821 button
->justification
= justification
;
1823 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1824 gtk_sheet_button_draw(sheet
, row
, -1);
1825 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1830 gtk_sheet_column_button_justify(GtkSheet
*sheet
, gint column
,
1831 GtkJustification justification
)
1833 GtkSheetButton
*button
;
1835 g_return_if_fail (sheet
!= NULL
);
1836 g_return_if_fail (GTK_IS_SHEET (sheet
));
1838 if(column
< 0 || column
> sheet
->maxcol
) return;
1840 button
= &sheet
->column
[column
].button
;
1841 button
->justification
= justification
;
1843 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1844 gtk_sheet_button_draw(sheet
, -1, column
);
1845 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, column
);
1851 gtk_sheet_moveto (GtkSheet
* sheet
,
1858 guint width
, height
;
1860 gint min_row
, min_col
;
1862 g_return_if_fail (sheet
!= NULL
);
1863 g_return_if_fail (GTK_IS_SHEET (sheet
));
1864 g_return_if_fail (sheet
->hadjustment
!= NULL
);
1865 g_return_if_fail (sheet
->vadjustment
!= NULL
);
1867 if (row
< 0 || row
> sheet
->maxrow
)
1869 if (column
< 0 || column
> sheet
->maxcol
)
1872 height
= sheet
->sheet_window_height
;
1873 width
= sheet
->sheet_window_width
;
1875 /* adjust vertical scrollbar */
1877 if (row
>= 0 && row_align
>=0.)
1879 y
= ROW_TOP_YPIXEL(sheet
, row
) - sheet
->voffset
-
1881 (1.-row_align
)*sheet
->row
[row
].height
;
1883 /* This forces the sheet to scroll when you don't see the entire cell */
1886 if(row_align
== 1.){
1887 while(min_row
>= 0 && min_row
> MIN_VISIBLE_ROW(sheet
)){
1888 if(sheet
->row
[min_row
].is_visible
)
1889 adjust
+= sheet
->row
[min_row
].height
;
1890 if(adjust
>= height
){
1895 min_row
= MAX(min_row
, 0);
1896 y
= ROW_TOP_YPIXEL(sheet
, min_row
) - sheet
->voffset
+
1897 sheet
->row
[min_row
].height
- 1;
1901 sheet
->vadjustment
->value
= 0.0;
1903 sheet
->vadjustment
->value
= y
;
1905 sheet
->old_vadjustment
= -1.;
1906 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1911 /* adjust horizontal scrollbar */
1912 if (column
>= 0 && col_align
>= 0.)
1914 x
= COLUMN_LEFT_XPIXEL (sheet
, column
) - sheet
->hoffset
-
1916 (1.-col_align
)*sheet
->column
[column
].width
;
1918 /* This forces the sheet to scroll when you don't see the entire cell */
1921 if(col_align
== 1.){
1922 while(min_col
>= 0 && min_col
> MIN_VISIBLE_COLUMN(sheet
)){
1923 if(sheet
->column
[min_col
].is_visible
)
1924 adjust
+= sheet
->column
[min_col
].width
;
1925 if(adjust
>= width
){
1930 min_col
= MAX(min_col
, 0);
1931 x
= COLUMN_LEFT_XPIXEL(sheet
, min_col
) - sheet
->hoffset
+
1932 sheet
->column
[min_col
].width
- 1;
1936 sheet
->hadjustment
->value
= 0.0;
1938 sheet
->hadjustment
->value
= x
;
1940 sheet
->old_vadjustment
= -1.;
1941 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1948 gtk_sheet_column_set_sensitivity(GtkSheet
*sheet
, gint column
, gboolean sensitive
)
1950 g_return_if_fail (sheet
!= NULL
);
1951 g_return_if_fail (GTK_IS_SHEET (sheet
));
1953 if(column
< 0 || column
> sheet
->maxcol
) return;
1955 sheet
->column
[column
].is_sensitive
=sensitive
;
1957 sheet
->column
[column
].button
.state
=GTK_STATE_INSENSITIVE
;
1959 sheet
->column
[column
].button
.state
=GTK_STATE_NORMAL
;
1961 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
))
1962 gtk_sheet_button_draw(sheet
, -1, column
);
1967 gtk_sheet_columns_set_sensitivity(GtkSheet
*sheet
, gboolean sensitive
)
1971 g_return_if_fail (sheet
!= NULL
);
1972 g_return_if_fail (GTK_IS_SHEET (sheet
));
1974 for(i
=0; i
<=sheet
->maxcol
; i
++)
1975 gtk_sheet_column_set_sensitivity(sheet
, i
, sensitive
);
1979 gtk_sheet_columns_set_resizable (GtkSheet
*sheet
, gboolean resizable
)
1981 g_return_if_fail (sheet
!= NULL
);
1982 g_return_if_fail (GTK_IS_SHEET (sheet
));
1984 sheet
->columns_resizable
= resizable
;
1988 gtk_sheet_columns_resizable (GtkSheet
*sheet
)
1990 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1991 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1993 return sheet
->columns_resizable
;
1997 gtk_sheet_row_set_sensitivity(GtkSheet
*sheet
, gint row
, gboolean sensitive
)
2000 g_return_if_fail (sheet
!= NULL
);
2001 g_return_if_fail (GTK_IS_SHEET (sheet
));
2003 if(row
< 0 || row
> sheet
->maxrow
) return;
2005 sheet
->row
[row
].is_sensitive
=sensitive
;
2007 sheet
->row
[row
].button
.state
=GTK_STATE_INSENSITIVE
;
2009 sheet
->row
[row
].button
.state
=GTK_STATE_NORMAL
;
2011 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
))
2012 gtk_sheet_button_draw(sheet
, row
, -1);
2016 gtk_sheet_rows_set_sensitivity(GtkSheet
*sheet
, gboolean sensitive
)
2020 g_return_if_fail (sheet
!= NULL
);
2021 g_return_if_fail (GTK_IS_SHEET (sheet
));
2023 for(i
=0; i
<=sheet
->maxrow
; i
++)
2024 gtk_sheet_row_set_sensitivity(sheet
, i
, sensitive
);
2029 gtk_sheet_rows_set_resizable (GtkSheet
*sheet
, gboolean resizable
)
2031 g_return_if_fail (sheet
!= NULL
);
2032 g_return_if_fail (GTK_IS_SHEET (sheet
));
2034 sheet
->rows_resizable
= resizable
;
2038 gtk_sheet_rows_resizable (GtkSheet
*sheet
)
2040 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2041 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
2043 return sheet
->rows_resizable
;
2047 gtk_sheet_column_set_visibility(GtkSheet
*sheet
, gint column
, gboolean visible
)
2049 g_return_if_fail (sheet
!= NULL
);
2050 g_return_if_fail (GTK_IS_SHEET (sheet
));
2052 if(column
< 0 || column
> sheet
->maxcol
) return;
2053 if(sheet
->column
[column
].is_visible
== visible
) return;
2055 sheet
->column
[column
].is_visible
= visible
;
2057 gtk_sheet_recalc_left_xpixels(sheet
, column
);
2059 if(!GTK_SHEET_IS_FROZEN(sheet
) &&
2060 gtk_sheet_cell_isvisible(sheet
, MIN_VISIBLE_ROW(sheet
), column
)){
2061 gtk_sheet_range_draw(sheet
, NULL
);
2062 size_allocate_column_title_buttons(sheet
);
2067 gtk_sheet_row_set_visibility(GtkSheet
*sheet
, gint row
, gboolean visible
)
2069 g_return_if_fail (sheet
!= NULL
);
2070 g_return_if_fail (GTK_IS_SHEET (sheet
));
2072 if(row
< 0 || row
> sheet
->maxrow
) return;
2073 if(sheet
->row
[row
].is_visible
== visible
) return;
2075 sheet
->row
[row
].is_visible
= visible
;
2077 gtk_sheet_recalc_top_ypixels(sheet
, row
);
2079 if(!GTK_SHEET_IS_FROZEN(sheet
) &&
2080 gtk_sheet_cell_isvisible(sheet
, row
, MIN_VISIBLE_COLUMN(sheet
))){
2081 gtk_sheet_range_draw(sheet
, NULL
);
2082 size_allocate_row_title_buttons(sheet
);
2087 gtk_sheet_select_row (GtkSheet
* sheet
,
2090 g_return_if_fail (sheet
!= NULL
);
2091 g_return_if_fail (GTK_IS_SHEET (sheet
));
2093 if (row
< 0 || row
> sheet
->maxrow
)
2096 if(sheet
->state
!= GTK_SHEET_NORMAL
)
2097 gtk_sheet_real_unselect_range(sheet
, NULL
);
2100 gboolean veto
= TRUE
;
2101 veto
= gtk_sheet_deactivate_cell(sheet
);
2105 sheet
->state
=GTK_SHEET_ROW_SELECTED
;
2106 sheet
->range
.row0
=row
;
2107 sheet
->range
.col0
=0;
2108 sheet
->range
.rowi
=row
;
2109 sheet
->range
.coli
=sheet
->maxcol
;
2110 sheet
->active_cell
.row
=row
;
2111 sheet
->active_cell
.col
=0;
2113 gtk_signal_emit (GTK_OBJECT (sheet
), sheet_signals
[SELECT_ROW
], row
);
2114 gtk_sheet_real_select_range(sheet
, NULL
);
2120 gtk_sheet_select_column (GtkSheet
* sheet
,
2124 g_return_if_fail (sheet
!= NULL
);
2125 g_return_if_fail (GTK_IS_SHEET (sheet
));
2127 if (column
< 0 || column
> sheet
->maxcol
)
2130 if(sheet
->state
!= GTK_SHEET_NORMAL
)
2131 gtk_sheet_real_unselect_range(sheet
, NULL
);
2134 gboolean veto
= TRUE
;
2135 veto
= gtk_sheet_deactivate_cell(sheet
);
2139 sheet
->state
=GTK_SHEET_COLUMN_SELECTED
;
2140 sheet
->range
.row0
=0;
2141 sheet
->range
.col0
=column
;
2142 sheet
->range
.rowi
=sheet
->maxrow
;
2143 sheet
->range
.coli
=column
;
2144 sheet
->active_cell
.row
=0;
2145 sheet
->active_cell
.col
=column
;
2147 gtk_signal_emit (GTK_OBJECT (sheet
), sheet_signals
[SELECT_COLUMN
], column
);
2148 gtk_sheet_real_select_range(sheet
, NULL
);
2153 gtk_sheet_clip_range (GtkSheet
*sheet
, const GtkSheetRange
*range
)
2156 g_return_if_fail (sheet
!= NULL
);
2157 g_return_if_fail (GTK_IS_SHEET (sheet
));
2159 if(GTK_SHEET_IN_CLIP(sheet
)) return;
2161 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_CLIP
);
2164 sheet
->clip_range
= sheet
->range
;
2166 sheet
->clip_range
=*range
;
2169 sheet
->clip_timer
=gtk_timeout_add(TIMEOUT_FLASH
, gtk_sheet_flash
, sheet
);
2171 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CLIP_RANGE
],
2172 &sheet
->clip_range
);
2177 gtk_sheet_unclip_range(GtkSheet
*sheet
)
2180 g_return_if_fail (sheet
!= NULL
);
2181 g_return_if_fail (GTK_IS_SHEET (sheet
));
2183 if(!GTK_SHEET_IN_CLIP(sheet
)) return;
2185 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_CLIP
);
2186 gtk_timeout_remove(sheet
->clip_timer
);
2187 gtk_sheet_range_draw(sheet
, &sheet
->clip_range
);
2189 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
2190 gtk_sheet_range_draw(sheet
, &sheet
->range
);
2194 gtk_sheet_in_clip (GtkSheet
*sheet
)
2196 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2197 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
2199 return GTK_SHEET_IN_CLIP(sheet
);
2203 gtk_sheet_flash(gpointer data
)
2206 gint x
,y
,width
,height
;
2207 GdkRectangle clip_area
;
2209 sheet
=GTK_SHEET(data
);
2211 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return TRUE
;
2212 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return TRUE
;
2213 if(!gtk_sheet_range_isvisible(sheet
, sheet
->clip_range
)) return TRUE
;
2214 if(GTK_SHEET_IN_XDRAG(sheet
)) return TRUE
;
2215 if(GTK_SHEET_IN_YDRAG(sheet
)) return TRUE
;
2217 GDK_THREADS_ENTER();
2219 x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.col0
)+1;
2220 y
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.row0
)+1;
2221 width
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.coli
)-x
+
2222 sheet
->column
[sheet
->clip_range
.coli
].width
-1;
2223 height
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.rowi
)-y
+
2224 sheet
->row
[sheet
->clip_range
.rowi
].height
-1;
2226 clip_area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
2227 clip_area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
2228 clip_area
.width
=sheet
->sheet_window_width
;
2229 clip_area
.height
=sheet
->sheet_window_height
;
2235 if(width
>clip_area
.width
) width
=clip_area
.width
+10;
2240 if(height
>clip_area
.height
) height
=clip_area
.height
+10;
2242 gdk_draw_pixmap(sheet
->sheet_window
,
2243 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2249 gdk_draw_pixmap(sheet
->sheet_window
,
2250 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2256 gdk_draw_pixmap(sheet
->sheet_window
,
2257 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2263 gdk_draw_pixmap(sheet
->sheet_window
,
2264 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2271 sheet
->interval
=sheet
->interval
+1;
2272 if(sheet
->interval
==TIME_INTERVAL
) sheet
->interval
=0;
2274 gdk_gc_set_dashes(sheet
->xor_gc
, sheet
->interval
, (gint8
*)"\4\4", 2);
2275 gtk_sheet_draw_flashing_range(sheet
,sheet
->clip_range
);
2276 gdk_gc_set_dashes(sheet
->xor_gc
, 0, (gint8
*)"\4\4", 2);
2278 GDK_THREADS_LEAVE();
2285 gtk_sheet_draw_flashing_range(GtkSheet
*sheet
, GtkSheetRange range
)
2287 GdkRectangle clip_area
;
2288 gint x
,y
,width
,height
;
2290 if(!gtk_sheet_range_isvisible(sheet
, sheet
->clip_range
)) return;
2292 clip_area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
2293 clip_area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
2294 clip_area
.width
=sheet
->sheet_window_width
;
2295 clip_area
.height
=sheet
->sheet_window_height
;
2297 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &clip_area
);
2299 x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.col0
)+1;
2300 y
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.row0
)+1;
2301 width
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.coli
)-x
+
2302 sheet
->column
[sheet
->clip_range
.coli
].width
-1;
2303 height
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.rowi
)-y
+
2304 sheet
->row
[sheet
->clip_range
.rowi
].height
-1;
2310 if(width
>clip_area
.width
) width
=clip_area
.width
+10;
2315 if(height
>clip_area
.height
) height
=clip_area
.height
+10;
2317 gdk_gc_set_line_attributes(sheet
->xor_gc
, 1, 1, 0 ,0 );
2319 gdk_draw_rectangle(sheet
->sheet_window
, sheet
->xor_gc
, FALSE
,
2323 gdk_gc_set_line_attributes (sheet
->xor_gc
, 1, 0, 0, 0);
2325 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
2330 gtk_sheet_range_isvisible (GtkSheet
* sheet
,
2331 GtkSheetRange range
)
2333 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2335 if (range
.row0
< 0 || range
.row0
> sheet
->maxrow
)
2338 if (range
.rowi
< 0 || range
.rowi
> sheet
->maxrow
)
2341 if (range
.col0
< 0 || range
.col0
> sheet
->maxcol
)
2344 if (range
.coli
< 0 || range
.coli
> sheet
->maxcol
)
2347 if (range
.rowi
< MIN_VISIBLE_ROW (sheet
))
2350 if (range
.row0
> MAX_VISIBLE_ROW (sheet
))
2353 if (range
.coli
< MIN_VISIBLE_COLUMN (sheet
))
2356 if (range
.col0
> MAX_VISIBLE_COLUMN (sheet
))
2363 gtk_sheet_cell_isvisible (GtkSheet
* sheet
,
2364 gint row
, gint column
)
2366 GtkSheetRange range
;
2369 range
.col0
= column
;
2371 range
.coli
= column
;
2373 return gtk_sheet_range_isvisible(sheet
, range
);
2377 gtk_sheet_get_visible_range(GtkSheet
*sheet
, GtkSheetRange
*range
)
2380 g_return_if_fail (sheet
!= NULL
);
2381 g_return_if_fail (GTK_IS_SHEET (sheet
)) ;
2382 g_return_if_fail (range
!= NULL
);
2384 range
->row0
= MIN_VISIBLE_ROW(sheet
);
2385 range
->col0
= MIN_VISIBLE_COLUMN(sheet
);
2386 range
->rowi
= MAX_VISIBLE_ROW(sheet
);
2387 range
->coli
= MAX_VISIBLE_COLUMN(sheet
);
2392 gtk_sheet_get_vadjustment (GtkSheet
* sheet
)
2394 g_return_val_if_fail (sheet
!= NULL
, NULL
);
2395 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
2397 return sheet
->vadjustment
;
2401 gtk_sheet_get_hadjustment (GtkSheet
* sheet
)
2403 g_return_val_if_fail (sheet
!= NULL
, NULL
);
2404 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
2406 return sheet
->hadjustment
;
2410 gtk_sheet_set_vadjustment (GtkSheet
*sheet
,
2411 GtkAdjustment
*adjustment
)
2413 GtkAdjustment
*old_adjustment
;
2415 g_return_if_fail (sheet
!= NULL
);
2416 g_return_if_fail (GTK_IS_SHEET (sheet
));
2418 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment
));
2420 if (sheet
->vadjustment
== adjustment
)
2423 old_adjustment
= sheet
->vadjustment
;
2425 if (sheet
->vadjustment
)
2427 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->vadjustment
), sheet
);
2428 gtk_object_unref (GTK_OBJECT (sheet
->vadjustment
));
2431 sheet
->vadjustment
= adjustment
;
2433 if (sheet
->vadjustment
)
2435 gtk_object_ref (GTK_OBJECT (sheet
->vadjustment
));
2436 gtk_object_sink (GTK_OBJECT (sheet
->vadjustment
));
2438 gtk_signal_connect (GTK_OBJECT (sheet
->vadjustment
), "changed",
2439 (GtkSignalFunc
) vadjustment_changed
,
2441 gtk_signal_connect (GTK_OBJECT (sheet
->vadjustment
), "value_changed",
2442 (GtkSignalFunc
) vadjustment_value_changed
,
2446 if (!sheet
->vadjustment
|| !old_adjustment
)
2448 gtk_widget_queue_resize (GTK_WIDGET (sheet
));
2452 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
2456 gtk_sheet_set_hadjustment (GtkSheet
*sheet
,
2457 GtkAdjustment
*adjustment
)
2459 GtkAdjustment
*old_adjustment
;
2461 g_return_if_fail (sheet
!= NULL
);
2462 g_return_if_fail (GTK_IS_SHEET (sheet
));
2464 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment
));
2466 if (sheet
->hadjustment
== adjustment
)
2469 old_adjustment
= sheet
->hadjustment
;
2471 if (sheet
->hadjustment
)
2473 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->hadjustment
), sheet
);
2474 gtk_object_unref (GTK_OBJECT (sheet
->hadjustment
));
2477 sheet
->hadjustment
= adjustment
;
2479 if (sheet
->hadjustment
)
2481 gtk_object_ref (GTK_OBJECT (sheet
->hadjustment
));
2482 gtk_object_sink (GTK_OBJECT (sheet
->hadjustment
));
2484 gtk_signal_connect (GTK_OBJECT (sheet
->hadjustment
), "changed",
2485 (GtkSignalFunc
) hadjustment_changed
,
2487 gtk_signal_connect (GTK_OBJECT (sheet
->hadjustment
), "value_changed",
2488 (GtkSignalFunc
) hadjustment_value_changed
,
2492 if (!sheet
->hadjustment
|| !old_adjustment
)
2494 gtk_widget_queue_resize (GTK_WIDGET (sheet
));
2498 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
2502 gtk_sheet_set_scroll_adjustments (GtkSheet
*sheet
,
2503 GtkAdjustment
*hadjustment
,
2504 GtkAdjustment
*vadjustment
)
2506 if(sheet
->hadjustment
!= hadjustment
)
2507 gtk_sheet_set_hadjustment (sheet
, hadjustment
);
2508 if(sheet
->vadjustment
!= vadjustment
)
2509 gtk_sheet_set_vadjustment (sheet
, vadjustment
);
2513 gtk_sheet_finalize (GObject
* object
)
2517 g_return_if_fail (object
!= NULL
);
2518 g_return_if_fail (GTK_IS_SHEET (object
));
2520 sheet
= GTK_SHEET (object
);
2522 /* get rid of all the cells */
2523 gtk_sheet_range_clear (sheet
, NULL
);
2524 gtk_sheet_range_delete(sheet
, NULL
);
2526 gtk_sheet_delete_rows (sheet
, 0, sheet
->maxrow
+ 1);
2527 gtk_sheet_delete_columns (sheet
, 0, sheet
->maxcol
+ 1);
2529 DeleteRow (sheet
, 0, sheet
->maxrow
+ 1);
2530 DeleteColumn (sheet
, 0, sheet
->maxcol
+ 1);
2534 g_free(sheet
->column
);
2535 sheet
->column
= NULL
;
2536 g_free(sheet
->data
);
2540 g_free(sheet
->name
);
2544 if (G_OBJECT_CLASS (parent_class
)->finalize
)
2545 (*G_OBJECT_CLASS (parent_class
)->finalize
) (object
);
2549 gtk_sheet_destroy (GtkObject
* object
)
2554 g_return_if_fail (object
!= NULL
);
2555 g_return_if_fail (GTK_IS_SHEET (object
));
2557 sheet
= GTK_SHEET (object
);
2559 /* destroy the entry */
2560 if(sheet
->sheet_entry
&& GTK_IS_WIDGET(sheet
->sheet_entry
)){
2561 gtk_widget_destroy (sheet
->sheet_entry
);
2562 sheet
->sheet_entry
= NULL
;
2565 /* destroy the global selection button */
2566 if(sheet
->button
&& GTK_IS_WIDGET(sheet
->button
)){
2567 gtk_widget_destroy (sheet
->button
);
2568 sheet
->button
= NULL
;
2572 gtk_timeout_remove(sheet
->timer
);
2576 if(sheet
->clip_timer
){
2577 gtk_timeout_remove(sheet
->clip_timer
);
2578 sheet
->clip_timer
= 0;
2581 /* unref adjustments */
2582 if (sheet
->hadjustment
)
2584 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->hadjustment
), sheet
);
2585 gtk_object_unref (GTK_OBJECT (sheet
->hadjustment
));
2586 sheet
->hadjustment
= NULL
;
2588 if (sheet
->vadjustment
)
2590 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->vadjustment
), sheet
);
2591 gtk_object_unref (GTK_OBJECT (sheet
->vadjustment
));
2592 sheet
->vadjustment
= NULL
;
2595 children
= sheet
->children
;
2597 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
2598 if(child
&& child
->widget
)
2599 gtk_sheet_remove(GTK_CONTAINER(sheet
), child
->widget
);
2600 children
= sheet
->children
;
2602 sheet
->children
= NULL
;
2604 if (GTK_OBJECT_CLASS (parent_class
)->destroy
)
2605 (*GTK_OBJECT_CLASS (parent_class
)->destroy
) (object
);
2609 gtk_sheet_style_set (GtkWidget
*widget
,
2610 GtkStyle
*previous_style
)
2614 g_return_if_fail (widget
!= NULL
);
2615 g_return_if_fail (GTK_IS_SHEET (widget
));
2617 if (GTK_WIDGET_CLASS (parent_class
)->style_set
)
2618 (*GTK_WIDGET_CLASS (parent_class
)->style_set
) (widget
, previous_style
);
2620 sheet
= GTK_SHEET (widget
);
2622 if(GTK_WIDGET_REALIZED(widget
))
2624 gtk_style_set_background (widget
->style
, widget
->window
, widget
->state
);
2630 gtk_sheet_realize (GtkWidget
* widget
)
2633 GdkWindowAttr attributes
;
2634 gint attributes_mask
;
2635 GdkGCValues values
, auxvalues
;
2636 GdkColormap
*colormap
;
2638 GtkSheetChild
*child
;
2641 g_return_if_fail (widget
!= NULL
);
2642 g_return_if_fail (GTK_IS_SHEET (widget
));
2644 sheet
= GTK_SHEET (widget
);
2646 GTK_WIDGET_SET_FLAGS (widget
, GTK_REALIZED
);
2648 attributes
.window_type
= GDK_WINDOW_CHILD
;
2649 attributes
.x
= widget
->allocation
.x
;
2650 attributes
.y
= widget
->allocation
.y
;
2651 attributes
.width
= widget
->allocation
.width
;
2652 attributes
.height
= widget
->allocation
.height
;
2653 attributes
.wclass
= GDK_INPUT_OUTPUT
;
2655 attributes
.visual
= gtk_widget_get_visual (widget
);
2656 attributes
.colormap
= gtk_widget_get_colormap (widget
);
2658 attributes
.event_mask
= gtk_widget_get_events (widget
);
2659 attributes
.event_mask
|= (GDK_EXPOSURE_MASK
|
2660 GDK_BUTTON_PRESS_MASK
|
2661 GDK_BUTTON_RELEASE_MASK
|
2662 GDK_KEY_PRESS_MASK
|
2663 GDK_POINTER_MOTION_MASK
|
2664 GDK_POINTER_MOTION_HINT_MASK
);
2665 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
|
2668 attributes
.cursor
= gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
2671 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
, attributes_mask
);
2673 gdk_window_set_user_data (widget
->window
, sheet
);
2675 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
2677 gtk_style_set_background (widget
->style
, widget
->window
, GTK_STATE_NORMAL
);
2680 if(sheet
->row_titles_visible
)
2681 attributes
.x
= sheet
->row_title_area
.width
;
2683 attributes
.width
= sheet
->column_title_area
.width
;
2684 attributes
.height
= sheet
->column_title_area
.height
;
2686 /* column-title window */
2687 sheet
->column_title_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2688 gdk_window_set_user_data (sheet
->column_title_window
, sheet
);
2689 gtk_style_set_background (widget
->style
, sheet
->column_title_window
, GTK_STATE_NORMAL
);
2693 if(sheet
->column_titles_visible
)
2694 attributes
.y
= sheet
->column_title_area
.height
;
2695 attributes
.width
= sheet
->row_title_area
.width
;
2696 attributes
.height
= sheet
->row_title_area
.height
;
2698 /* row-title window */
2699 sheet
->row_title_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2700 gdk_window_set_user_data (sheet
->row_title_window
, sheet
);
2701 gtk_style_set_background (widget
->style
, sheet
->row_title_window
, GTK_STATE_NORMAL
);
2704 attributes
.cursor
= gdk_cursor_new(GDK_PLUS
);
2708 attributes
.width
= sheet
->sheet_window_width
,
2709 attributes
.height
= sheet
->sheet_window_height
;
2711 sheet
->sheet_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2712 gdk_window_set_user_data (sheet
->sheet_window
, sheet
);
2714 gdk_window_set_background (sheet
->sheet_window
, &widget
->style
->white
);
2715 gdk_window_show (sheet
->sheet_window
);
2717 /* backing_pixmap */
2718 gtk_sheet_make_backing_pixmap(sheet
, 0, 0);
2722 gdk_gc_unref(sheet
->fg_gc
);
2724 gdk_gc_unref(sheet
->bg_gc
);
2725 sheet
->fg_gc
= gdk_gc_new (widget
->window
);
2726 sheet
->bg_gc
= gdk_gc_new (widget
->window
);
2728 colormap
= gtk_widget_get_colormap(widget
);
2730 gdk_color_white(colormap
, &widget
->style
->white
);
2731 gdk_color_black(colormap
, &widget
->style
->black
);
2733 gdk_gc_get_values(sheet
->fg_gc
, &auxvalues
);
2735 values
.foreground
= widget
->style
->white
;
2736 values
.function
= GDK_INVERT
;
2737 values
.subwindow_mode
= GDK_INCLUDE_INFERIORS
;
2739 gdk_gc_unref(sheet
->xor_gc
);
2740 sheet
->xor_gc
= gdk_gc_new_with_values (widget
->window
,
2746 if(sheet
->sheet_entry
->parent
){
2747 gtk_widget_ref(sheet
->sheet_entry
);
2748 gtk_widget_unparent(sheet
->sheet_entry
);
2750 gtk_widget_set_parent_window (sheet
->sheet_entry
, sheet
->sheet_window
);
2751 gtk_widget_set_parent(sheet
->sheet_entry
, GTK_WIDGET(sheet
));
2753 if(sheet
->button
&& sheet
->button
->parent
){
2754 gtk_widget_ref(sheet
->button
);
2755 gtk_widget_unparent(sheet
->button
);
2757 gtk_widget_set_parent_window(sheet
->button
, sheet
->sheet_window
);
2758 gtk_widget_set_parent(sheet
->button
, GTK_WIDGET(sheet
));
2761 gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col);
2763 if(!sheet
->cursor_drag
)
2764 sheet
->cursor_drag
= gdk_cursor_new(GDK_PLUS
);
2766 if(sheet
->column_titles_visible
)
2767 gdk_window_show(sheet
->column_title_window
);
2768 if(sheet
->row_titles_visible
)
2769 gdk_window_show(sheet
->row_title_window
);
2771 size_allocate_row_title_buttons(sheet
);
2772 size_allocate_column_title_buttons(sheet
);
2774 name
= g_strdup(sheet
->name
);
2775 gtk_sheet_set_title(sheet
, name
);
2779 children
= sheet
->children
;
2782 child
= children
->data
;
2783 children
= g_list_next(children
);
2785 gtk_sheet_realize_child(sheet
, child
);
2790 create_global_button(GtkSheet
*sheet
)
2792 sheet
->button
= gtk_button_new_with_label(" ");
2794 gtk_signal_connect (GTK_OBJECT (sheet
->button
),
2796 (GtkSignalFunc
) global_button_clicked
,
2801 size_allocate_global_button(GtkSheet
*sheet
)
2803 GtkAllocation allocation
;
2805 if(!sheet
->column_titles_visible
) return;
2806 if(!sheet
->row_titles_visible
) return;
2808 gtk_widget_size_request(sheet
->button
, NULL
);
2812 allocation
.width
=sheet
->row_title_area
.width
;
2813 allocation
.height
=sheet
->column_title_area
.height
;
2815 gtk_widget_size_allocate(sheet
->button
, &allocation
);
2816 gtk_widget_show(sheet
->button
);
2820 global_button_clicked(GtkWidget
*widget
, gpointer data
)
2824 gtk_sheet_click_cell(GTK_SHEET(data
), -1, -1, &veto
);
2825 gtk_widget_grab_focus(GTK_WIDGET(data
));
2830 gtk_sheet_unrealize (GtkWidget
* widget
)
2834 g_return_if_fail (widget
!= NULL
);
2835 g_return_if_fail (GTK_IS_SHEET (widget
));
2837 sheet
= GTK_SHEET (widget
);
2839 gdk_cursor_destroy (sheet
->cursor_drag
);
2841 gdk_gc_destroy (sheet
->xor_gc
);
2842 gdk_gc_destroy (sheet
->fg_gc
);
2843 gdk_gc_destroy (sheet
->bg_gc
);
2845 gdk_window_destroy (sheet
->sheet_window
);
2846 gdk_window_destroy (sheet
->column_title_window
);
2847 gdk_window_destroy (sheet
->row_title_window
);
2850 g_object_unref (sheet
->pixmap
);
2851 sheet
->pixmap
= NULL
;
2854 sheet
->column_title_window
=NULL
;
2855 sheet
->sheet_window
= NULL
;
2856 sheet
->cursor_drag
= NULL
;
2857 sheet
->xor_gc
= NULL
;
2858 sheet
->fg_gc
= NULL
;
2859 sheet
->bg_gc
= NULL
;
2861 if (GTK_WIDGET_CLASS (parent_class
)->unrealize
)
2862 (* GTK_WIDGET_CLASS (parent_class
)->unrealize
) (widget
);
2866 gtk_sheet_map (GtkWidget
* widget
)
2869 GtkSheetChild
*child
;
2872 g_return_if_fail (widget
!= NULL
);
2873 g_return_if_fail (GTK_IS_SHEET (widget
));
2875 sheet
= GTK_SHEET (widget
);
2877 if (!GTK_WIDGET_MAPPED (widget
))
2879 GTK_WIDGET_SET_FLAGS (widget
, GTK_MAPPED
);
2881 if(!sheet
->cursor_drag
) sheet
->cursor_drag
=gdk_cursor_new(GDK_PLUS
);
2883 gdk_window_show (widget
->window
);
2885 gdk_window_show (sheet
->sheet_window
);
2887 if(sheet
->column_titles_visible
){
2888 gdk_window_show (sheet
->column_title_window
);
2890 if(sheet
->row_titles_visible
){
2891 gdk_window_show (sheet
->row_title_window
);
2894 if(!GTK_WIDGET_MAPPED (sheet
->sheet_entry
)){
2895 gtk_widget_show (sheet
->sheet_entry
);
2896 gtk_widget_map (sheet
->sheet_entry
);
2899 if (GTK_WIDGET_VISIBLE (sheet
->button
) &&
2900 !GTK_WIDGET_MAPPED (sheet
->button
)){
2901 gtk_widget_show(sheet
->button
);
2902 gtk_widget_map (sheet
->button
);
2905 if(GTK_BIN(sheet
->button
)->child
)
2906 if (GTK_WIDGET_VISIBLE (GTK_BIN(sheet
->button
)->child
) &&
2907 !GTK_WIDGET_MAPPED (GTK_BIN(sheet
->button
)->child
))
2908 gtk_widget_map (GTK_BIN(sheet
->button
)->child
);
2910 gtk_sheet_range_draw(sheet
, NULL
);
2911 gtk_sheet_activate_cell(sheet
,
2912 sheet
->active_cell
.row
,
2913 sheet
->active_cell
.col
);
2915 children
= sheet
->children
;
2918 child
= children
->data
;
2919 children
= g_list_next(children
);
2921 if (GTK_WIDGET_VISIBLE (child
->widget
) &&
2922 !GTK_WIDGET_MAPPED (child
->widget
)){
2923 gtk_widget_map (child
->widget
);
2924 gtk_sheet_position_child(sheet
, child
);
2932 gtk_sheet_unmap (GtkWidget
* widget
)
2935 GtkSheetChild
*child
;
2938 g_return_if_fail (widget
!= NULL
);
2939 g_return_if_fail (GTK_IS_SHEET (widget
));
2941 sheet
= GTK_SHEET (widget
);
2943 if (GTK_WIDGET_MAPPED (widget
))
2945 GTK_WIDGET_UNSET_FLAGS (widget
, GTK_MAPPED
);
2947 gdk_window_hide (sheet
->sheet_window
);
2948 if(sheet
->column_titles_visible
)
2949 gdk_window_hide (sheet
->column_title_window
);
2950 if(sheet
->row_titles_visible
)
2951 gdk_window_hide (sheet
->row_title_window
);
2952 gdk_window_hide (widget
->window
);
2954 if (GTK_WIDGET_MAPPED (sheet
->sheet_entry
))
2955 gtk_widget_unmap (sheet
->sheet_entry
);
2957 if (GTK_WIDGET_MAPPED (sheet
->button
))
2958 gtk_widget_unmap (sheet
->button
);
2960 children
= sheet
->children
;
2963 child
= children
->data
;
2964 children
= g_list_next(children
);
2966 if (GTK_WIDGET_VISIBLE (child
->widget
) &&
2967 GTK_WIDGET_MAPPED (child
->widget
))
2969 gtk_widget_unmap (child
->widget
);
2978 gtk_sheet_cell_draw_default (GtkSheet
*sheet
, gint row
, gint col
)
2981 GdkGC
*fg_gc
, *bg_gc
;
2982 GtkSheetCellAttr attributes
;
2985 g_return_if_fail (sheet
!= NULL
);
2987 /* bail now if we arn't drawable yet */
2988 if (!GTK_WIDGET_DRAWABLE (sheet
)) return;
2990 if (row
< 0 || row
> sheet
->maxrow
) return;
2991 if (col
< 0 || col
> sheet
->maxcol
) return;
2992 if (!sheet
->column
[col
].is_visible
) return;
2993 if (!sheet
->row
[row
].is_visible
) return;
2995 widget
= GTK_WIDGET (sheet
);
2997 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
2999 /* select GC for background rectangle */
3000 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.foreground
);
3001 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3003 fg_gc
= sheet
->fg_gc
;
3004 bg_gc
= sheet
->bg_gc
;
3006 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3007 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3008 area
.width
=sheet
->column
[col
].width
;
3009 area
.height
=sheet
->row
[row
].height
;
3011 gdk_draw_rectangle (sheet
->pixmap
,
3019 gdk_gc_set_line_attributes (sheet
->fg_gc
, 1, 0, 0, 0);
3021 if(sheet
->show_grid
){
3022 gdk_gc_set_foreground (sheet
->bg_gc
, &sheet
->grid_color
);
3024 gdk_draw_rectangle (sheet
->pixmap
,
3028 area
.width
, area
.height
);
3033 gtk_sheet_cell_draw_border (GtkSheet
*sheet
, gint row
, gint col
, gint mask
)
3036 GdkGC
*fg_gc
, *bg_gc
;
3037 GtkSheetCellAttr attributes
;
3041 g_return_if_fail (sheet
!= NULL
);
3043 /* bail now if we arn't drawable yet */
3044 if (!GTK_WIDGET_DRAWABLE (sheet
)) return;
3046 if (row
< 0 || row
> sheet
->maxrow
) return;
3047 if (col
< 0 || col
> sheet
->maxcol
) return;
3048 if (!sheet
->column
[col
].is_visible
) return;
3049 if (!sheet
->row
[row
].is_visible
) return;
3051 widget
= GTK_WIDGET (sheet
);
3053 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3055 /* select GC for background rectangle */
3056 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.border
.color
);
3057 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3059 fg_gc
= sheet
->fg_gc
;
3060 bg_gc
= sheet
->bg_gc
;
3062 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3063 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3064 area
.width
=sheet
->column
[col
].width
;
3065 area
.height
=sheet
->row
[row
].height
;
3067 width
= attributes
.border
.width
;
3068 gdk_gc_set_line_attributes(sheet
->fg_gc
, attributes
.border
.width
,
3069 attributes
.border
.line_style
,
3070 attributes
.border
.cap_style
,
3071 attributes
.border
.join_style
);
3074 if(attributes
.border
.mask
& GTK_SHEET_LEFT_BORDER
& mask
)
3075 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3076 area
.x
, area
.y
-width
/2,
3077 area
.x
, area
.y
+area
.height
+width
/2+1);
3079 if(attributes
.border
.mask
& GTK_SHEET_RIGHT_BORDER
& mask
)
3080 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3081 area
.x
+area
.width
, area
.y
-width
/2,
3083 area
.y
+area
.height
+width
/2+1);
3085 if(attributes
.border
.mask
& GTK_SHEET_TOP_BORDER
& mask
)
3086 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3087 area
.x
-width
/2,area
.y
,
3088 area
.x
+area
.width
+width
/2+1,
3091 if(attributes
.border
.mask
& GTK_SHEET_BOTTOM_BORDER
& mask
)
3092 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3093 area
.x
-width
/2, area
.y
+area
.height
,
3094 area
.x
+area
.width
+width
/2+1,
3095 area
.y
+area
.height
);
3102 gtk_sheet_cell_draw_label (GtkSheet
*sheet
, gint row
, gint col
)
3105 GdkRectangle area
, clip_area
;
3107 gint text_width
, text_height
, y
;
3109 gint size
, sizel
, sizer
;
3110 GdkGC
*fg_gc
, *bg_gc
;
3111 GtkSheetCellAttr attributes
;
3112 PangoLayout
*layout
;
3113 PangoRectangle rect
;
3114 PangoRectangle logical_rect
;
3115 PangoLayoutLine
*line
;
3116 PangoFontMetrics
*metrics
;
3117 PangoContext
*context
= gtk_widget_get_pango_context(GTK_WIDGET(sheet
));
3118 gint ascent
, descent
, y_pos
;
3122 g_return_if_fail (sheet
!= NULL
);
3124 /* bail now if we aren't drawable yet */
3125 if (!GTK_WIDGET_DRAWABLE (sheet
))
3128 if (row
> sheet
->maxallocrow
) return;
3129 if (col
> sheet
->maxalloccol
) return;
3130 if (!sheet
->data
[row
]) return;
3131 if (!sheet
->data
[row
][col
]) return;
3132 if (!sheet
->data
[row
][col
]->text
|| strlen(sheet
->data
[row
][col
]->text
)==0)
3135 if (row
< 0 || row
> sheet
->maxrow
) return;
3136 if (col
< 0 || col
> sheet
->maxcol
) return;
3137 if (!sheet
->column
[col
].is_visible
) return;
3138 if (!sheet
->row
[row
].is_visible
) return;
3141 widget
= GTK_WIDGET(sheet
);
3143 label
= sheet
->data
[row
][col
]->text
;
3145 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3147 /* select GC for background rectangle */
3148 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.foreground
);
3149 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3151 fg_gc
= sheet
->fg_gc
;
3152 bg_gc
= sheet
->bg_gc
;
3154 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3155 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3156 area
.width
=sheet
->column
[col
].width
;
3157 area
.height
=sheet
->row
[row
].height
;
3161 layout
= gtk_widget_create_pango_layout (GTK_WIDGET(sheet
), label
);
3162 pango_layout_set_font_description (layout
, attributes
.font_desc
);
3164 pango_layout_get_pixel_extents (layout
, NULL
, &rect
);
3166 line
= pango_layout_get_lines (layout
)->data
;
3167 pango_layout_line_get_extents (line
, NULL
, &logical_rect
);
3169 metrics
= pango_context_get_metrics(context
,
3170 attributes
.font_desc
,
3171 pango_context_get_language(context
));
3173 ascent
= pango_font_metrics_get_ascent(metrics
) / PANGO_SCALE
;
3174 descent
= pango_font_metrics_get_descent(metrics
) / PANGO_SCALE
;
3176 pango_font_metrics_unref(metrics
);
3178 /* Align primarily for locale's ascent/descent */
3180 logical_rect
.height
/= PANGO_SCALE
;
3181 logical_rect
.y
/= PANGO_SCALE
;
3182 y_pos
= area
.height
- logical_rect
.height
;
3184 if (logical_rect
.height
> area
.height
)
3185 y_pos
= (logical_rect
.height
- area
.height
- 2*CELLOFFSET
) / 2;
3188 else if (y_pos
+ logical_rect
.height
> area
.height
)
3189 y_pos
= area
.height
- logical_rect
.height
;
3191 text_width
= rect
.width
;
3192 text_height
= rect
.height
;
3193 y
= area
.y
+ y_pos
- CELLOFFSET
;
3195 switch(attributes
.justification
){
3196 case GTK_JUSTIFY_RIGHT
:
3199 if(!gtk_sheet_clip_text(sheet
)){
3200 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
3201 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3202 if(size
>=text_width
+CELLOFFSET
) break;
3203 size
+=sheet
->column
[i
].width
;
3204 sheet
->column
[i
].right_text_column
= MAX(col
, sheet
->column
[i
].right_text_column
);
3209 xoffset
+=area
.width
-text_width
- 2 * CELLOFFSET
-
3210 attributes
.border
.width
/2;
3212 case GTK_JUSTIFY_CENTER
:
3215 area
.x
+=area
.width
/2;
3216 if(!gtk_sheet_clip_text(sheet
)){
3217 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
3218 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3219 if(sizer
>=text_width
/2) break;
3220 sizer
+=sheet
->column
[i
].width
;
3221 sheet
->column
[i
].left_text_column
= MIN(col
, sheet
->column
[i
].left_text_column
);
3223 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
3224 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3225 if(sizel
>=text_width
/2) break;
3226 sizel
+=sheet
->column
[i
].width
;
3227 sheet
->column
[i
].right_text_column
= MAX(col
, sheet
->column
[i
].right_text_column
);
3229 size
=MIN(sizel
, sizer
);
3232 xoffset
+= sizel
- text_width
/2 - CELLOFFSET
;
3233 area
.width
=sizel
+sizer
;
3235 case GTK_JUSTIFY_LEFT
:
3238 if(!gtk_sheet_clip_text(sheet
)){
3239 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
3240 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3241 if(size
>=text_width
+CELLOFFSET
) break;
3242 size
+=sheet
->column
[i
].width
;
3243 sheet
->column
[i
].left_text_column
= MIN(col
, sheet
->column
[i
].left_text_column
);
3247 xoffset
+= attributes
.border
.width
/2;
3251 if(!gtk_sheet_clip_text(sheet
)) clip_area
= area
;
3252 gdk_gc_set_clip_rectangle(fg_gc
, &clip_area
);
3255 gdk_draw_layout (sheet
->pixmap
, fg_gc
,
3256 area
.x
+ xoffset
+ CELLOFFSET
,
3260 gdk_gc_set_clip_rectangle(fg_gc
, NULL
);
3261 g_object_unref(G_OBJECT(layout
));
3263 gdk_draw_pixmap(sheet
->sheet_window
,
3264 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3278 gtk_sheet_range_draw(GtkSheet
*sheet
, const GtkSheetRange
*range
)
3281 GtkSheetRange drawing_range
;
3284 g_return_if_fail(sheet
!= NULL
);
3285 g_return_if_fail(GTK_SHEET(sheet
));
3287 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return;
3288 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3289 if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
))) return;
3293 drawing_range
.row0
=MIN_VISIBLE_ROW(sheet
);
3294 drawing_range
.col0
=MIN_VISIBLE_COLUMN(sheet
);
3295 drawing_range
.rowi
=MAX_VISIBLE_ROW(sheet
);
3296 drawing_range
.coli
=MAX_VISIBLE_COLUMN(sheet
);
3298 gdk_draw_rectangle (sheet->pixmap,
3299 GTK_WIDGET(sheet)->style->white_gc,
3302 sheet->sheet_window_width,sheet->sheet_window_height);
3307 drawing_range
.row0
=MAX(range
->row0
, MIN_VISIBLE_ROW(sheet
));
3308 drawing_range
.col0
=MAX(range
->col0
, MIN_VISIBLE_COLUMN(sheet
));
3309 drawing_range
.rowi
=MIN(range
->rowi
, MAX_VISIBLE_ROW(sheet
));
3310 drawing_range
.coli
=MIN(range
->coli
, MAX_VISIBLE_COLUMN(sheet
));
3313 if(drawing_range
.coli
== sheet
->maxcol
){
3314 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->maxcol
)+
3315 sheet
->column
[sheet
->maxcol
].width
+1;
3318 gdk_gc_set_foreground(sheet
->fg_gc
, &sheet
->bg_color
);
3320 gdk_draw_rectangle (sheet
->pixmap
,
3324 sheet
->sheet_window_width
- area
.x
,
3325 sheet
->sheet_window_height
);
3327 gdk_draw_pixmap(sheet
->sheet_window
,
3328 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3334 sheet
->sheet_window_width
- area
.x
,
3335 sheet
->sheet_window_height
);
3337 if(drawing_range
.rowi
== sheet
->maxrow
){
3339 area
.y
=ROW_TOP_YPIXEL(sheet
,sheet
->maxrow
)+sheet
->row
[sheet
->maxrow
].height
+1;
3341 gdk_gc_set_foreground(sheet
->fg_gc
, &sheet
->bg_color
);
3343 gdk_draw_rectangle (sheet
->pixmap
,
3347 sheet
->sheet_window_width
,
3348 sheet
->sheet_window_height
- area
.y
);
3350 gdk_draw_pixmap(sheet
->sheet_window
,
3351 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3357 sheet
->sheet_window_width
,
3358 sheet
->sheet_window_height
- area
.y
);
3361 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3362 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++){
3363 gtk_sheet_cell_draw_default(sheet
, i
, j
);
3366 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3367 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++){
3368 gtk_sheet_cell_draw_border(sheet
, i
-1, j
, GTK_SHEET_BOTTOM_BORDER
);
3369 gtk_sheet_cell_draw_border(sheet
, i
+1, j
, GTK_SHEET_TOP_BORDER
);
3370 gtk_sheet_cell_draw_border(sheet
, i
, j
-1, GTK_SHEET_RIGHT_BORDER
);
3371 gtk_sheet_cell_draw_border(sheet
, i
, j
+1, GTK_SHEET_LEFT_BORDER
);
3372 gtk_sheet_cell_draw_border(sheet
, i
, j
, 15);
3375 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3376 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++)
3377 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3378 sheet
->data
[i
] && sheet
->data
[i
][j
])
3379 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3381 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3382 for(j
=sheet
->column
[drawing_range
.col0
].left_text_column
; j
<drawing_range
.col0
; j
++)
3383 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3384 sheet
->data
[i
] && sheet
->data
[i
][j
])
3385 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3387 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3388 for(j
=drawing_range
.coli
+1; j
<=sheet
->column
[drawing_range
.coli
].right_text_column
; j
++)
3389 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3390 sheet
->data
[i
] && sheet
->data
[i
][j
])
3391 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3393 gtk_sheet_draw_backing_pixmap(sheet
, drawing_range
);
3395 if(sheet
->state
!= GTK_SHEET_NORMAL
&& gtk_sheet_range_isvisible(sheet
, sheet
->range
))
3396 gtk_sheet_range_draw_selection(sheet
, drawing_range
);
3398 if(sheet
->state
== GTK_STATE_NORMAL
&&
3399 sheet
->active_cell
.row
>= drawing_range
.row0
&&
3400 sheet
->active_cell
.row
<= drawing_range
.rowi
&&
3401 sheet
->active_cell
.col
>= drawing_range
.col0
&&
3402 sheet
->active_cell
.col
<= drawing_range
.coli
)
3403 gtk_sheet_show_active_cell(sheet
);
3408 gtk_sheet_range_draw_selection(GtkSheet
*sheet
, GtkSheetRange range
)
3414 if(range
.col0
> sheet
->range
.coli
|| range
.coli
< sheet
->range
.col0
||
3415 range
.row0
> sheet
->range
.rowi
|| range
.rowi
< sheet
->range
.row0
)
3418 if(!gtk_sheet_range_isvisible(sheet
, range
)) return;
3419 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3423 range
.col0
=MAX(sheet
->range
.col0
, range
.col0
);
3424 range
.coli
=MIN(sheet
->range
.coli
, range
.coli
);
3425 range
.row0
=MAX(sheet
->range
.row0
, range
.row0
);
3426 range
.rowi
=MIN(sheet
->range
.rowi
, range
.rowi
);
3428 range
.col0
=MAX(range
.col0
, MIN_VISIBLE_COLUMN(sheet
));
3429 range
.coli
=MIN(range
.coli
, MAX_VISIBLE_COLUMN(sheet
));
3430 range
.row0
=MAX(range
.row0
, MIN_VISIBLE_ROW(sheet
));
3431 range
.rowi
=MIN(range
.rowi
, MAX_VISIBLE_ROW(sheet
));
3433 for(i
=range
.row0
; i
<=range
.rowi
; i
++){
3434 for(j
=range
.col0
; j
<=range
.coli
; j
++){
3436 if(gtk_sheet_cell_get_state(sheet
, i
, j
)==GTK_STATE_SELECTED
&&
3437 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
3439 row_button_set(sheet
, i
);
3440 column_button_set(sheet
, j
);
3442 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
3443 area
.y
=ROW_TOP_YPIXEL(sheet
,i
);
3444 area
.width
=sheet
->column
[j
].width
;
3445 area
.height
=sheet
->row
[i
].height
;
3447 if(i
==sheet
->range
.row0
){
3449 area
.height
=area
.height
-2;
3451 if(i
==sheet
->range
.rowi
) area
.height
=area
.height
-3;
3452 if(j
==sheet
->range
.col0
){
3454 area
.width
=area
.width
-2;
3456 if(j
==sheet
->range
.coli
) area
.width
=area
.width
-3;
3458 if(i
!=sheet
->active_cell
.row
|| j
!=sheet
->active_cell
.col
){
3459 gdk_draw_rectangle (sheet
->sheet_window
,
3463 area
.width
,area
.height
);
3470 gtk_sheet_draw_border(sheet
, sheet
->range
);
3475 gtk_sheet_draw_backing_pixmap(GtkSheet
*sheet
, GtkSheetRange range
)
3477 gint x
,y
,width
,height
;
3479 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3481 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
3482 y
=ROW_TOP_YPIXEL(sheet
, range
.row0
);
3483 width
=COLUMN_LEFT_XPIXEL(sheet
, range
.coli
)-x
+sheet
->column
[range
.coli
].width
;
3484 height
=ROW_TOP_YPIXEL(sheet
, range
.rowi
)-y
+sheet
->row
[range
.rowi
].height
;
3486 if(range
.row0
==sheet
->range
.row0
){
3490 if(range
.rowi
==sheet
->range
.rowi
) height
=height
+5;
3491 if(range
.col0
==sheet
->range
.col0
){
3495 if(range
.coli
==sheet
->range
.coli
) width
=width
+5;
3498 width
=MIN(width
, sheet
->sheet_window_width
-x
);
3499 height
=MIN(height
, sheet
->sheet_window_height
-y
);
3506 x
= (sheet
->row_titles_visible
)
3507 ? MAX(x
, sheet
->row_title_area
.width
) : MAX(x
, 0);
3508 y
= (sheet
->column_titles_visible
)
3509 ? MAX(y
, sheet
->column_title_area
.height
) : MAX(y
, 0);
3511 if(range
.coli
==sheet
->maxcol
) width
=sheet
->sheet_window_width
-x
;
3512 if(range
.rowi
==sheet
->maxrow
) height
=sheet
->sheet_window_height
-y
;
3514 gdk_draw_pixmap(sheet
->sheet_window
,
3515 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3525 static GtkSheetCell
*
3526 gtk_sheet_cell_new()
3529 cell
= g_new(GtkSheetCell
, 1);
3532 cell
->attributes
= NULL
;
3537 gtk_sheet_set_cell_text(GtkSheet
*sheet
, gint row
, gint col
, const gchar
*text
)
3539 GtkSheetCellAttr attributes
;
3541 g_return_if_fail (sheet
!= NULL
);
3542 g_return_if_fail (GTK_IS_SHEET (sheet
));
3543 if (col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3544 if (col
< 0 || row
< 0) return;
3546 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3547 gtk_sheet_set_cell(sheet
, row
, col
, attributes
.justification
, text
);
3551 gtk_sheet_set_cell(GtkSheet
*sheet
, gint row
, gint col
,
3552 GtkJustification justification
,
3555 GtkSheetCell
**cell
;
3556 GtkSheetRange range
;
3558 GtkSheetCellAttr attributes
;
3560 g_return_if_fail (sheet
!= NULL
);
3561 g_return_if_fail (GTK_IS_SHEET (sheet
));
3562 if (col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3563 if (col
< 0 || row
< 0) return;
3565 CheckBounds(sheet
, row
, col
);
3567 cell
=&sheet
->data
[row
][col
];
3570 (*cell
) = gtk_sheet_cell_new();
3572 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3577 attributes
.justification
= justification
;
3578 gtk_sheet_set_cell_attributes(sheet
, row
, col
, attributes
);
3581 g_free((*cell
)->text
);
3582 (*cell
)->text
= NULL
;
3586 (*cell
)->text
=g_strdup(text
);
3588 if(attributes
.is_visible
){
3591 if((*cell
)->text
&& strlen((*cell
)->text
) > 0) {
3592 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), attributes
.font_desc
, (*cell
)->text
);
3597 range
.col0
= sheet
->view
.col0
;
3598 range
.coli
= sheet
->view
.coli
;
3600 if(gtk_sheet_autoresize(sheet
) &&
3601 text_width
> sheet
->column
[col
].width
-2*CELLOFFSET
-attributes
.border
.width
){
3602 gtk_sheet_set_column_width(sheet
, col
, text_width
+2*CELLOFFSET
+attributes
.border
.width
);
3603 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_REDRAW_PENDING
);
3606 if(!GTK_SHEET_IS_FROZEN(sheet
))
3607 gtk_sheet_range_draw(sheet
, &range
);
3609 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, col
);
3615 gtk_sheet_cell_clear (GtkSheet
*sheet
, gint row
, gint column
)
3617 GtkSheetRange range
;
3619 g_return_if_fail (sheet
!= NULL
);
3620 g_return_if_fail (GTK_IS_SHEET (sheet
));
3621 if (column
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3622 if (column
> sheet
->maxalloccol
|| row
> sheet
->maxallocrow
) return;
3623 if (column
< 0 || row
< 0) return;
3627 range
.col0
= sheet
->view
.col0
;
3628 range
.coli
= sheet
->view
.coli
;
3630 gtk_sheet_real_cell_clear(sheet
, row
, column
, FALSE
);
3632 if(!GTK_SHEET_IS_FROZEN(sheet
)){
3633 gtk_sheet_range_draw(sheet
, &range
);
3638 gtk_sheet_cell_delete (GtkSheet
*sheet
, gint row
, gint column
)
3640 GtkSheetRange range
;
3642 g_return_if_fail (sheet
!= NULL
);
3643 g_return_if_fail (GTK_IS_SHEET (sheet
));
3644 if (column
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3645 if (column
> sheet
->maxalloccol
|| row
> sheet
->maxallocrow
) return;
3646 if (column
< 0 || row
< 0) return;
3650 range
.col0
= sheet
->view
.col0
;
3651 range
.coli
= sheet
->view
.coli
;
3653 gtk_sheet_real_cell_clear(sheet
, row
, column
, TRUE
);
3655 if(!GTK_SHEET_IS_FROZEN(sheet
)){
3656 gtk_sheet_range_draw(sheet
, &range
);
3661 gtk_sheet_real_cell_clear (GtkSheet
*sheet
, gint row
, gint column
, gboolean
delete)
3666 if(row
> sheet
->maxallocrow
|| column
> sheet
->maxalloccol
) return;
3667 if(!sheet
->data
[row
]) return;
3668 if(!sheet
->data
[row
][column
]) return;
3670 text
= gtk_sheet_cell_get_text(sheet
, row
, column
);
3671 link
= gtk_sheet_get_link(sheet
, row
, column
);
3674 g_free(sheet
->data
[row
][column
]->text
);
3675 sheet
->data
[row
][column
]->text
= NULL
;
3677 if(GTK_IS_OBJECT(sheet
) && G_OBJECT(sheet
)->ref_count
> 0)
3678 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CLEAR_CELL
], row
, column
);
3682 if(sheet
->data
[row
][column
]->attributes
){
3683 g_free(sheet
->data
[row
][column
]->attributes
);
3684 sheet
->data
[row
][column
]->attributes
= NULL
;
3686 sheet
->data
[row
][column
]->link
= NULL
;
3688 if(sheet
->data
[row
][column
]) g_free(sheet
->data
[row
][column
]);
3690 sheet
->data
[row
][column
] = NULL
;
3696 gtk_sheet_range_clear (GtkSheet
*sheet
, const GtkSheetRange
*range
)
3698 g_return_if_fail (sheet
!= NULL
);
3699 g_return_if_fail (GTK_IS_SHEET (sheet
));
3701 gtk_sheet_real_range_clear(sheet
, range
, FALSE
);
3705 gtk_sheet_range_delete (GtkSheet
*sheet
, const GtkSheetRange
*range
)
3707 g_return_if_fail (sheet
!= NULL
);
3708 g_return_if_fail (GTK_IS_SHEET (sheet
));
3710 gtk_sheet_real_range_clear(sheet
, range
, TRUE
);
3714 gtk_sheet_real_range_clear (GtkSheet
*sheet
, const GtkSheetRange
*range
,
3718 GtkSheetRange clear
;
3722 clear
.rowi
=sheet
->maxallocrow
;
3724 clear
.coli
=sheet
->maxalloccol
;
3728 clear
.row0
=MAX(clear
.row0
, 0);
3729 clear
.col0
=MAX(clear
.col0
, 0);
3730 clear
.rowi
=MIN(clear
.rowi
, sheet
->maxallocrow
);
3731 clear
.coli
=MIN(clear
.coli
, sheet
->maxalloccol
);
3733 for(i
=clear
.row0
; i
<=clear
.rowi
; i
++)
3734 for(j
=clear
.col0
; j
<=clear
.coli
; j
++){
3735 gtk_sheet_real_cell_clear(sheet
, i
, j
, delete);
3738 gtk_sheet_range_draw(sheet
, NULL
);
3743 gtk_sheet_cell_get_text (GtkSheet
*sheet
, gint row
, gint col
)
3745 g_return_val_if_fail (sheet
!= NULL
, NULL
);
3746 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
3748 if(col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return NULL
;
3749 if(col
< 0 || row
< 0) return NULL
;
3750 if(row
> sheet
->maxallocrow
|| col
> sheet
->maxalloccol
) return NULL
;
3751 if(!sheet
->data
[row
]) return NULL
;
3752 if(!sheet
->data
[row
][col
]) return NULL
;
3753 if(!sheet
->data
[row
][col
]->text
) return NULL
;
3754 if(strlen(sheet
->data
[row
][col
]->text
) == 0) return NULL
;
3756 return (sheet
->data
[row
][col
]->text
);
3760 gtk_sheet_link_cell(GtkSheet
*sheet
, gint row
, gint col
, gpointer link
)
3762 g_return_if_fail (sheet
!= NULL
);
3763 g_return_if_fail (GTK_IS_SHEET (sheet
));
3764 if(col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3765 if(col
< 0 || row
< 0) return;
3767 if(row
> sheet
->maxallocrow
|| col
> sheet
->maxalloccol
||
3768 !sheet
->data
[row
] || !sheet
->data
[row
][col
])
3769 gtk_sheet_set_cell_text(sheet
, row
, col
, "");
3771 sheet
->data
[row
][col
]->link
= link
;
3775 gtk_sheet_get_link(GtkSheet
*sheet
, gint row
, gint col
)
3777 g_return_val_if_fail (sheet
!= NULL
, NULL
);
3778 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
3779 if(col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return NULL
;
3780 if(col
< 0 || row
< 0) return NULL
;
3782 if (row
> sheet
->maxallocrow
|| col
> sheet
->maxalloccol
) return NULL
;
3783 if (!sheet
->data
[row
]) return NULL
; /* Added by Chris Howell */
3784 if (!sheet
->data
[row
][col
]) return NULL
; /* Added by Bob Lissner */
3786 return(sheet
->data
[row
][col
]->link
);
3790 gtk_sheet_remove_link(GtkSheet
*sheet
, gint row
, gint col
)
3792 g_return_if_fail (sheet
!= NULL
);
3793 g_return_if_fail (GTK_IS_SHEET (sheet
));
3794 if(col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3795 if(col
< 0 || row
< 0) return;
3797 /* Fixed by Andreas Voegele */
3798 if(row
< sheet
->maxallocrow
&& col
< sheet
->maxalloccol
&&
3799 sheet
->data
[row
] && sheet
->data
[row
][col
] &&
3800 sheet
->data
[row
][col
]->link
)
3801 sheet
->data
[row
][col
]->link
= NULL
;
3806 gtk_sheet_cell_get_state (GtkSheet
*sheet
, gint row
, gint col
)
3809 GtkSheetRange
*range
;
3811 g_return_val_if_fail (sheet
!= NULL
, 0);
3812 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
3813 if(col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return 0;
3814 if(col
< 0 || row
< 0) return 0;
3816 state
= sheet
->state
;
3817 range
= &sheet
->range
;
3820 case GTK_SHEET_NORMAL
:
3821 return GTK_STATE_NORMAL
;
3823 case GTK_SHEET_ROW_SELECTED
:
3824 if(row
>=range
->row0
&& row
<=range
->rowi
)
3825 return GTK_STATE_SELECTED
;
3827 case GTK_SHEET_COLUMN_SELECTED
:
3828 if(col
>=range
->col0
&& col
<=range
->coli
)
3829 return GTK_STATE_SELECTED
;
3831 case GTK_SHEET_RANGE_SELECTED
:
3832 if(row
>= range
->row0
&& row
<= range
->rowi
&& \
3833 col
>= range
->col0
&& col
<= range
->coli
)
3834 return GTK_STATE_SELECTED
;
3837 return GTK_STATE_NORMAL
;
3841 gtk_sheet_get_pixel_info (GtkSheet
* sheet
,
3849 g_return_val_if_fail (sheet
!= NULL
, 0);
3850 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
3852 /* bounds checking, return false if the user clicked
3853 * on a blank area */
3854 trow
= ROW_FROM_YPIXEL (sheet
, y
);
3855 if (trow
> sheet
->maxrow
)
3860 tcol
= COLUMN_FROM_XPIXEL (sheet
, x
);
3861 if (tcol
> sheet
->maxcol
)
3870 gtk_sheet_get_cell_area (GtkSheet
* sheet
,
3875 g_return_val_if_fail (sheet
!= NULL
, 0);
3876 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
3878 if(row
> sheet
->maxrow
|| column
> sheet
->maxcol
) return FALSE
;
3880 area
->x
= (column
== -1) ? 0 : (COLUMN_LEFT_XPIXEL(sheet
, column
) -
3881 (sheet
->row_titles_visible
3882 ? sheet
->row_title_area
.width
3884 area
->y
= (row
== -1) ? 0 : (ROW_TOP_YPIXEL(sheet
, row
) -
3885 (sheet
->column_titles_visible
3886 ? sheet
->column_title_area
.height
3888 area
->width
= (column
== -1) ? sheet
->row_title_area
.width
3889 : sheet
->column
[column
].width
;
3890 area
->height
= (row
== -1) ? sheet
->column_title_area
.height
3891 : sheet
->row
[row
].height
;
3894 if(row < 0 || column < 0) return FALSE;
3896 area->x = COLUMN_LEFT_XPIXEL(sheet, column);
3897 area->y = ROW_TOP_YPIXEL(sheet, row);
3898 if(sheet->row_titles_visible)
3899 area->x -= sheet->row_title_area.width;
3900 if(sheet->column_titles_visible)
3901 area->y -= sheet->column_title_area.height;
3903 area->width=sheet->column[column].width;
3904 area->height=sheet->row[row].height;
3910 gtk_sheet_set_active_cell (GtkSheet
*sheet
, gint row
, gint column
)
3912 g_return_val_if_fail (sheet
!= NULL
, 0);
3913 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
3915 if(row
< 0 || column
< 0) return FALSE
;
3916 if(row
> sheet
->maxrow
|| column
> sheet
->maxcol
) return FALSE
;
3918 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)))
3920 if(!gtk_sheet_deactivate_cell(sheet
)) return FALSE
;
3923 sheet
->active_cell
.row
=row
;
3924 sheet
->active_cell
.col
=column
;
3926 if(!gtk_sheet_activate_cell(sheet
, row
, column
)) return FALSE
;
3932 gtk_sheet_get_active_cell (GtkSheet
*sheet
, gint
*row
, gint
*column
)
3934 g_return_if_fail (sheet
!= NULL
);
3935 g_return_if_fail (GTK_IS_SHEET (sheet
));
3937 *row
= sheet
->active_cell
.row
;
3938 *column
= sheet
->active_cell
.col
;
3942 gtk_sheet_entry_changed(GtkWidget
*widget
, gpointer data
)
3947 GtkJustification justification
;
3948 GtkSheetCellAttr attributes
;
3950 g_return_if_fail (data
!= NULL
);
3951 g_return_if_fail (GTK_IS_SHEET (data
));
3953 sheet
=GTK_SHEET(data
);
3955 if(!GTK_WIDGET_VISIBLE(widget
)) return;
3956 if(sheet
->state
!= GTK_STATE_NORMAL
) return;
3958 row
=sheet
->active_cell
.row
;
3959 col
=sheet
->active_cell
.col
;
3961 if(row
<0 || col
<0) return;
3963 sheet
->active_cell
.row
=-1;
3964 sheet
->active_cell
.col
=-1;
3966 text
=gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
3968 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
3970 if(text
&& strlen(text
)!=0){
3971 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3972 justification
=attributes
.justification
;
3973 gtk_sheet_set_cell(sheet
, row
, col
, justification
, text
);
3977 /* Added by Matias Mutchinick */
3978 gtk_sheet_cell_clear(sheet
, row
, col
);
3981 if(sheet
->freeze_count
== 0)
3982 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
3984 sheet
->active_cell
.row
=row
;;
3985 sheet
->active_cell
.col
=col
;
3991 gtk_sheet_deactivate_cell(GtkSheet
*sheet
)
3993 gboolean veto
= TRUE
;
3995 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
3996 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
3998 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return FALSE
;
3999 if(sheet
->state
!= GTK_SHEET_NORMAL
) return FALSE
;
4001 _gtkextra_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[DEACTIVATE
],
4002 sheet
->active_cell
.row
,
4003 sheet
->active_cell
.col
, &veto
);
4005 if(!veto
) return FALSE
;
4007 gtk_signal_disconnect_by_func(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
4008 (GtkSignalFunc
) gtk_sheet_entry_changed
,
4009 GTK_OBJECT(GTK_WIDGET(sheet
)));
4011 gtk_sheet_hide_active_cell(sheet
);
4012 sheet
->active_cell
.row
=-1;
4013 sheet
->active_cell
.col
=-1;
4015 if(GTK_SHEET_REDRAW_PENDING(sheet
)){
4016 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_REDRAW_PENDING
);
4017 gtk_sheet_range_draw(sheet
, NULL
);
4024 gtk_sheet_hide_active_cell(GtkSheet
*sheet
)
4028 GtkJustification justification
;
4029 GtkSheetCellAttr attributes
;
4031 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4033 row
=sheet
->active_cell
.row
;
4034 col
=sheet
->active_cell
.col
;
4036 if(row
< 0 || col
< 0) return;
4038 if(sheet
->freeze_count
== 0)
4039 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
4041 text
=gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
4043 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
4044 justification
=attributes
.justification
;
4046 if(text
&& strlen(text
)!=0){
4047 gtk_sheet_set_cell(sheet
, row
, col
, justification
, text
);
4048 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[SET_CELL
], row
, col
);
4052 gtk_sheet_cell_clear(sheet
, row
, col
);
4055 row
=sheet
->active_cell
.row
;
4056 col
=sheet
->active_cell
.col
;
4058 column_button_release(sheet
, col
);
4059 row_button_release(sheet
, row
);
4061 gtk_widget_unmap(sheet
->sheet_entry
);
4063 if(row
!= -1 && col
!= -1)
4064 gdk_draw_pixmap(sheet
->sheet_window
,
4065 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4067 COLUMN_LEFT_XPIXEL(sheet
,col
)-1,
4068 ROW_TOP_YPIXEL(sheet
,row
)-1,
4069 COLUMN_LEFT_XPIXEL(sheet
,col
)-1,
4070 ROW_TOP_YPIXEL(sheet
,row
)-1,
4071 sheet
->column
[col
].width
+4,
4072 sheet
->row
[row
].height
+4);
4074 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
4075 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet
), GTK_HAS_FOCUS
);
4076 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4078 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(sheet
->sheet_entry
), GTK_VISIBLE
);
4083 gtk_sheet_activate_cell(GtkSheet
*sheet
, gint row
, gint col
)
4085 gboolean veto
= TRUE
;
4087 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
4088 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
4090 if(row
< 0 || col
< 0) return FALSE
;
4091 if(row
> sheet
->maxrow
|| col
> sheet
->maxcol
) return FALSE
;
4093 /* _gtkextra_signal_emit(GTK_OBJECT(sheet),sheet_signals[ACTIVATE], row, col, &veto);
4094 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return veto;
4097 if(!veto
) return FALSE
;
4098 if(sheet
->state
!= GTK_SHEET_NORMAL
){
4099 sheet
->state
=GTK_SHEET_NORMAL
;
4100 gtk_sheet_real_unselect_range(sheet
, NULL
);
4103 sheet
->range
.row0
=row
;
4104 sheet
->range
.col0
=col
;
4105 sheet
->range
.rowi
=row
;
4106 sheet
->range
.coli
=col
;
4107 sheet
->active_cell
.row
=row
;
4108 sheet
->active_cell
.col
=col
;
4109 sheet
->selection_cell
.row
=row
;
4110 sheet
->selection_cell
.col
=col
;
4111 row_button_set(sheet
, row
);
4112 column_button_set(sheet
, col
);
4114 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
4115 gtk_sheet_show_active_cell(sheet
);
4117 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
4119 (GtkSignalFunc
)gtk_sheet_entry_changed
,
4120 GTK_OBJECT(GTK_WIDGET(sheet
)));
4122 _gtkextra_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[ACTIVATE
], row
, col
, &veto
);
4128 gtk_sheet_show_active_cell(GtkSheet
*sheet
)
4131 GtkEntry
*sheet_entry
;
4132 GtkSheetCellAttr attributes
;
4134 GtkJustification justification
;
4137 g_return_if_fail (sheet
!= NULL
);
4138 g_return_if_fail (GTK_IS_SHEET (sheet
));
4140 row
= sheet
->active_cell
.row
;
4141 col
= sheet
->active_cell
.col
;
4143 /* Don't show the active cell, if there is no active cell: */
4144 if(!(row
>= 0 && col
>= 0)) /* e.g row or coll == -1. */
4147 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4148 if(sheet
->state
!= GTK_SHEET_NORMAL
) return;
4149 if(GTK_SHEET_IN_SELECTION(sheet
)) return;
4151 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet
->sheet_entry
), GTK_VISIBLE
);
4153 sheet_entry
= GTK_ENTRY(gtk_sheet_get_entry(sheet
));
4155 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
4157 justification
= GTK_JUSTIFY_LEFT
;
4159 if(gtk_sheet_justify_entry(sheet
))
4160 justification
= attributes
.justification
;
4162 if(row
<= sheet
->maxallocrow
&& col
<= sheet
->maxalloccol
) {
4163 if(sheet
->data
[row
]) {
4164 if(sheet
->data
[row
][col
]) {
4165 cell
= sheet
->data
[row
][col
];
4167 text
= g_strdup(cell
->text
);
4172 if(!text
) text
= g_strdup("");
4174 gtk_entry_set_visibility(GTK_ENTRY(sheet_entry
), attributes
.is_visible
);
4176 if(gtk_sheet_locked(sheet
) || !attributes
.is_editable
){
4177 gtk_entry_set_editable(GTK_ENTRY(sheet_entry
), FALSE
);
4179 gtk_entry_set_editable(GTK_ENTRY(sheet_entry
), TRUE
);
4183 if(!GTK_IS_ITEM_ENTRY(sheet_entry
))
4184 gtk_entry_set_text(GTK_ENTRY(sheet_entry
), text
);
4186 gtk_item_entry_set_text(GTK_ITEM_ENTRY(sheet_entry
), text
, justification
);
4189 gtk_sheet_entry_set_max_size(sheet
);
4190 gtk_sheet_size_allocate_entry(sheet
);
4192 gtk_widget_map(sheet
->sheet_entry
);
4193 gtk_sheet_draw_active_cell(sheet
);
4195 gtk_widget_grab_focus(GTK_WIDGET(sheet_entry
));
4196 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet_entry
), GTK_HAS_FOCUS
);
4197 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(sheet
), GTK_HAS_FOCUS
);
4203 gtk_sheet_draw_active_cell(GtkSheet
*sheet
)
4207 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return;
4208 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4210 row
= sheet
->active_cell
.row
;
4211 col
= sheet
->active_cell
.col
;
4213 if(row
<0 || col
<0) return;
4215 if(!gtk_sheet_cell_isvisible(sheet
, row
, col
)) return;
4217 row_button_set(sheet
, row
);
4218 column_button_set(sheet
, col
);
4220 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4221 gtk_sheet_draw_border(sheet
, sheet
->range
);
4227 gtk_sheet_make_backing_pixmap (GtkSheet
*sheet
, guint width
, guint height
)
4229 gint pixmap_width
, pixmap_height
;
4231 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4233 if(width
== 0 && height
== 0){
4234 width
=sheet
->sheet_window_width
+80;
4235 height
=sheet
->sheet_window_height
+80;
4241 sheet
->pixmap
= gdk_pixmap_new (sheet
->sheet_window
,
4244 if(!GTK_SHEET_IS_FROZEN(sheet
)) gtk_sheet_range_draw(sheet
, NULL
);
4248 /* reallocate if sizes don't match */
4249 gdk_window_get_size (sheet
->pixmap
,
4250 &pixmap_width
, &pixmap_height
);
4251 if ((pixmap_width
!= width
) || (pixmap_height
!= height
))
4253 gdk_pixmap_unref(sheet
->pixmap
); /* replaced by SDB on 7.31.2006 */
4254 /* g_free(sheet->pixmap); */
4255 sheet
->pixmap
= gdk_pixmap_new (sheet
->sheet_window
,
4258 if(!GTK_SHEET_IS_FROZEN(sheet
)) gtk_sheet_range_draw(sheet
, NULL
);
4264 gtk_sheet_new_selection(GtkSheet
*sheet
, GtkSheetRange
*range
)
4266 gint i
,j
, mask1
, mask2
;
4267 gint state
, selected
;
4268 gint x
,y
,width
,height
;
4269 GtkSheetRange new_range
, aux_range
;
4271 g_return_if_fail (sheet
!= NULL
);
4273 if(range
==NULL
) range
=&sheet
->range
;
4277 range
->row0
=MIN(range
->row0
, sheet
->range
.row0
);
4278 range
->rowi
=MAX(range
->rowi
, sheet
->range
.rowi
);
4279 range
->col0
=MIN(range
->col0
, sheet
->range
.col0
);
4280 range
->coli
=MAX(range
->coli
, sheet
->range
.coli
);
4282 range
->row0
=MAX(range
->row0
, MIN_VISIBLE_ROW(sheet
));
4283 range
->rowi
=MIN(range
->rowi
, MAX_VISIBLE_ROW(sheet
));
4284 range
->col0
=MAX(range
->col0
, MIN_VISIBLE_COLUMN(sheet
));
4285 range
->coli
=MIN(range
->coli
, MAX_VISIBLE_COLUMN(sheet
));
4287 aux_range
.row0
=MAX(new_range
.row0
, MIN_VISIBLE_ROW(sheet
));
4288 aux_range
.rowi
=MIN(new_range
.rowi
, MAX_VISIBLE_ROW(sheet
));
4289 aux_range
.col0
=MAX(new_range
.col0
, MIN_VISIBLE_COLUMN(sheet
));
4290 aux_range
.coli
=MIN(new_range
.coli
, MAX_VISIBLE_COLUMN(sheet
));
4292 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4293 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4295 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4296 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4297 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4299 if(state
==GTK_STATE_SELECTED
&& selected
&&
4300 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
&&
4301 (i
==sheet
->range
.row0
|| i
==sheet
->range
.rowi
||
4302 j
==sheet
->range
.col0
|| j
==sheet
->range
.coli
||
4303 i
==new_range
.row0
|| i
==new_range
.rowi
||
4304 j
==new_range
.col0
|| j
==new_range
.coli
)){
4306 mask1
= i
==sheet
->range
.row0
? 1 : 0;
4307 mask1
= i
==sheet
->range
.rowi
? mask1
+2 : mask1
;
4308 mask1
= j
==sheet
->range
.col0
? mask1
+4 : mask1
;
4309 mask1
= j
==sheet
->range
.coli
? mask1
+8 : mask1
;
4311 mask2
= i
==new_range
.row0
? 1 : 0;
4312 mask2
= i
==new_range
.rowi
? mask2
+2 : mask2
;
4313 mask2
= j
==new_range
.col0
? mask2
+4 : mask2
;
4314 mask2
= j
==new_range
.coli
? mask2
+8 : mask2
;
4317 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4318 y
=ROW_TOP_YPIXEL(sheet
, i
);
4319 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4320 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4322 if(i
==sheet
->range
.row0
){
4326 if(i
==sheet
->range
.rowi
) height
=height
+3;
4327 if(j
==sheet
->range
.col0
){
4331 if(j
==sheet
->range
.coli
) width
=width
+3;
4333 gdk_draw_pixmap(sheet
->sheet_window
,
4334 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4343 if(i
!= sheet
->active_cell
.row
|| j
!= sheet
->active_cell
.col
){
4344 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4345 y
=ROW_TOP_YPIXEL(sheet
, i
);
4346 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4347 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4349 if(i
==new_range
.row0
){
4353 if(i
==new_range
.rowi
) height
=height
-3;
4354 if(j
==new_range
.col0
){
4358 if(j
==new_range
.coli
) width
=width
-3;
4360 gdk_draw_rectangle (sheet
->sheet_window
,
4371 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4372 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4374 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4375 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4376 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4378 if(state
==GTK_STATE_SELECTED
&& !selected
&&
4379 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
4381 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4382 y
=ROW_TOP_YPIXEL(sheet
, i
);
4383 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4384 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4386 if(i
==sheet
->range
.row0
){
4390 if(i
==sheet
->range
.rowi
) height
=height
+3;
4391 if(j
==sheet
->range
.col0
){
4395 if(j
==sheet
->range
.coli
) width
=width
+3;
4397 gdk_draw_pixmap(sheet
->sheet_window
,
4398 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4410 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4411 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4413 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4414 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4415 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4417 if(state
!=GTK_STATE_SELECTED
&& selected
&&
4418 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
&&
4419 (i
!= sheet
->active_cell
.row
|| j
!= sheet
->active_cell
.col
)){
4421 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4422 y
=ROW_TOP_YPIXEL(sheet
, i
);
4423 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4424 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4426 if(i
==new_range
.row0
){
4430 if(i
==new_range
.rowi
) height
=height
-3;
4431 if(j
==new_range
.col0
){
4435 if(j
==new_range
.coli
) width
=width
-3;
4437 gdk_draw_rectangle (sheet
->sheet_window
,
4448 for(i
=aux_range
.row0
; i
<=aux_range
.rowi
; i
++){
4449 for(j
=aux_range
.col0
; j
<=aux_range
.coli
; j
++){
4451 if(sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
4453 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4455 mask1
= i
==sheet
->range
.row0
? 1 : 0;
4456 mask1
= i
==sheet
->range
.rowi
? mask1
+2 : mask1
;
4457 mask1
= j
==sheet
->range
.col0
? mask1
+4 : mask1
;
4458 mask1
= j
==sheet
->range
.coli
? mask1
+8 : mask1
;
4460 mask2
= i
==new_range
.row0
? 1 : 0;
4461 mask2
= i
==new_range
.rowi
? mask2
+2 : mask2
;
4462 mask2
= j
==new_range
.col0
? mask2
+4 : mask2
;
4463 mask2
= j
==new_range
.coli
? mask2
+8 : mask2
;
4464 if(mask2
!=mask1
|| (mask2
==mask1
&& state
!=GTK_STATE_SELECTED
)){
4465 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4466 y
=ROW_TOP_YPIXEL(sheet
, i
);
4467 width
=sheet
->column
[j
].width
;
4468 height
=sheet
->row
[i
].height
;
4470 gdk_draw_rectangle (sheet
->sheet_window
,
4478 gdk_draw_rectangle (sheet
->sheet_window
,
4485 gdk_draw_rectangle (sheet
->sheet_window
,
4493 gdk_draw_rectangle (sheet
->sheet_window
,
4510 gtk_sheet_draw_corners(sheet
, new_range
);
4515 gtk_sheet_draw_border (GtkSheet
*sheet
, GtkSheetRange new_range
)
4520 gint x
,y
,width
,height
;
4522 widget
= GTK_WIDGET(sheet
);
4524 x
=COLUMN_LEFT_XPIXEL(sheet
,new_range
.col0
);
4525 y
=ROW_TOP_YPIXEL(sheet
,new_range
.row0
);
4526 width
=COLUMN_LEFT_XPIXEL(sheet
,new_range
.coli
)-x
+
4527 sheet
->column
[new_range
.coli
].width
;
4528 height
=ROW_TOP_YPIXEL(sheet
,new_range
.rowi
)-y
+
4529 sheet
->row
[new_range
.rowi
].height
;
4531 area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
4532 area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
4533 area
.width
=sheet
->sheet_window_width
;
4534 area
.height
=sheet
->sheet_window_height
;
4540 if(width
>area
.width
) width
=area
.width
+10;
4545 if(height
>area
.height
) height
=area
.height
+10;
4547 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &area
);
4549 for(i
=-1; i
<=1; ++i
)
4550 gdk_draw_rectangle (sheet
->sheet_window
,
4554 width
-2*i
,height
-2*i
);
4556 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
4558 gtk_sheet_draw_corners(sheet
, new_range
);
4563 gtk_sheet_draw_corners(GtkSheet
*sheet
, GtkSheetRange range
)
4568 if(gtk_sheet_cell_isvisible(sheet
, range
.row0
, range
.col0
)){
4569 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
4570 y
=ROW_TOP_YPIXEL(sheet
,range
.row0
);
4571 gdk_draw_pixmap(sheet
->sheet_window
,
4572 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4580 gdk_draw_rectangle (sheet
->sheet_window
,
4587 if(gtk_sheet_cell_isvisible(sheet
, range
.row0
, range
.coli
) ||
4588 sheet
->state
== GTK_SHEET_COLUMN_SELECTED
){
4589 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.coli
)+
4590 sheet
->column
[range
.coli
].width
;
4591 y
=ROW_TOP_YPIXEL(sheet
,range
.row0
);
4593 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
4595 y
= ROW_TOP_YPIXEL(sheet
, sheet
->view
.row0
)+3;
4598 gdk_draw_pixmap(sheet
->sheet_window
,
4599 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4607 gdk_draw_rectangle (sheet
->sheet_window
,
4610 x
-width
+width
/2,y
-width
+width
/2,
4614 if(gtk_sheet_cell_isvisible(sheet
, range
.rowi
, range
.col0
) ||
4615 sheet
->state
== GTK_SHEET_ROW_SELECTED
){
4616 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
4617 y
=ROW_TOP_YPIXEL(sheet
,range
.rowi
)+
4618 sheet
->row
[range
.rowi
].height
;
4620 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
4622 x
= COLUMN_LEFT_XPIXEL(sheet
, sheet
->view
.col0
)+3;
4625 gdk_draw_pixmap(sheet
->sheet_window
,
4626 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4634 gdk_draw_rectangle (sheet
->sheet_window
,
4637 x
-width
+width
/2,y
-width
+width
/2,
4641 if(gtk_sheet_cell_isvisible(sheet
, range
.rowi
, range
.coli
)){
4642 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.coli
)+
4643 sheet
->column
[range
.coli
].width
;
4644 y
=ROW_TOP_YPIXEL(sheet
,range
.rowi
)+
4645 sheet
->row
[range
.rowi
].height
;
4647 if(sheet
->state
== GTK_SHEET_RANGE_SELECTED
) width
= 3;
4648 if(sheet
->state
== GTK_SHEET_NORMAL
) width
= 3;
4649 gdk_draw_pixmap(sheet
->sheet_window
,
4650 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4658 gdk_draw_rectangle (sheet
->sheet_window
,
4661 x
-width
+width
/2,y
-width
+width
/2,
4670 gtk_sheet_real_select_range (GtkSheet
* sheet
,
4671 GtkSheetRange
* range
)
4676 g_return_if_fail (sheet
!= NULL
);
4678 if(range
==NULL
) range
=&sheet
->range
;
4680 if(range
->row0
< 0 || range
->rowi
< 0) return;
4681 if(range
->col0
< 0 || range
->coli
< 0) return;
4685 if(state
==GTK_SHEET_COLUMN_SELECTED
|| state
==GTK_SHEET_RANGE_SELECTED
){
4686 for(i
=sheet
->range
.col0
; i
< range
->col0
; i
++)
4687 column_button_release(sheet
, i
);
4688 for(i
=range
->coli
+1; i
<= sheet
->range
.coli
; i
++)
4689 column_button_release(sheet
, i
);
4690 for(i
=range
->col0
; i
<=range
->coli
; i
++){
4691 column_button_set(sheet
, i
);
4695 if(state
==GTK_SHEET_ROW_SELECTED
|| state
==GTK_SHEET_RANGE_SELECTED
){
4696 for(i
=sheet
->range
.row0
; i
< range
->row0
; i
++)
4697 row_button_release(sheet
, i
);
4698 for(i
=range
->rowi
+1; i
<= sheet
->range
.rowi
; i
++)
4699 row_button_release(sheet
, i
);
4700 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4701 row_button_set(sheet
, i
);
4705 if(range
->coli
!= sheet
->range
.coli
|| range
->col0
!= sheet
->range
.col0
||
4706 range
->rowi
!= sheet
->range
.rowi
|| range
->row0
!= sheet
->range
.row0
)
4709 gtk_sheet_new_selection(sheet
, range
);
4711 sheet
->range
.col0
=range
->col0
;
4712 sheet
->range
.coli
=range
->coli
;
4713 sheet
->range
.row0
=range
->row0
;
4714 sheet
->range
.rowi
=range
->rowi
;
4719 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4720 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
4723 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[SELECT_RANGE
], range
);
4727 gtk_sheet_select_range(GtkSheet
* sheet
, const GtkSheetRange
*range
)
4729 g_return_if_fail (sheet
!= NULL
);
4731 if(range
==NULL
) range
=&sheet
->range
;
4733 if(range
->row0
< 0 || range
->rowi
< 0) return;
4734 if(range
->col0
< 0 || range
->coli
< 0) return;
4736 if(sheet
->state
!= GTK_SHEET_NORMAL
)
4737 gtk_sheet_real_unselect_range(sheet
, NULL
);
4740 gboolean veto
= TRUE
;
4741 veto
= gtk_sheet_deactivate_cell(sheet
);
4745 sheet
->range
.row0
=range
->row0
;
4746 sheet
->range
.rowi
=range
->rowi
;
4747 sheet
->range
.col0
=range
->col0
;
4748 sheet
->range
.coli
=range
->coli
;
4749 sheet
->active_cell
.row
=range
->row0
;
4750 sheet
->active_cell
.col
=range
->col0
;
4751 sheet
->selection_cell
.row
=range
->rowi
;
4752 sheet
->selection_cell
.col
=range
->coli
;
4754 sheet
->state
= GTK_SHEET_RANGE_SELECTED
;
4755 gtk_sheet_real_select_range(sheet
, NULL
);
4760 gtk_sheet_unselect_range (GtkSheet
* sheet
)
4762 gtk_sheet_real_unselect_range(sheet
, NULL
);
4763 sheet
->state
= GTK_STATE_NORMAL
;
4764 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
);
4769 gtk_sheet_real_unselect_range (GtkSheet
* sheet
,
4770 const GtkSheetRange
*range
)
4774 g_return_if_fail (sheet
!= NULL
);
4775 g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)));
4778 range
=&sheet
->range
;
4781 if(range
->row0
< 0 || range
->rowi
< 0) return;
4782 if(range
->col0
< 0 || range
->coli
< 0) return;
4784 if (gtk_sheet_range_isvisible (sheet
, *range
)){
4785 gtk_sheet_draw_backing_pixmap(sheet
, *range
);
4788 for(i
=range
->col0
; i
<=range
->coli
; i
++){
4789 column_button_release(sheet
, i
);
4792 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4793 row_button_release(sheet
, i
);
4800 gtk_sheet_expose (GtkWidget
* widget
,
4801 GdkEventExpose
* event
)
4804 GtkSheetRange range
;
4807 printf("---> Entered gtk_sheet_expose ... must have received expose_event\n");
4810 g_return_val_if_fail (widget
!= NULL
, FALSE
);
4811 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
4812 g_return_val_if_fail (event
!= NULL
, FALSE
);
4814 sheet
= GTK_SHEET (widget
);
4816 if (GTK_WIDGET_DRAWABLE (widget
))
4818 range
.row0
=ROW_FROM_YPIXEL(sheet
,event
->area
.y
);
4819 range
.col0
=COLUMN_FROM_XPIXEL(sheet
,event
->area
.x
);
4820 range
.rowi
=ROW_FROM_YPIXEL(sheet
,event
->area
.y
+event
->area
.height
);
4821 range
.coli
=COLUMN_FROM_XPIXEL(sheet
,event
->area
.x
+event
->area
.width
);
4823 /* exposure events on the sheet */
4825 if( (event
->window
== sheet
->row_title_window
) && sheet
->row_titles_visible
){
4826 size_allocate_row_title_buttons(sheet
);
4829 if( (event
->window
== sheet
->column_title_window
) && sheet
->column_titles_visible
){
4830 size_allocate_column_title_buttons(sheet
);
4833 if (event
->window
== sheet
->sheet_window
){
4834 gtk_sheet_draw_backing_pixmap(sheet
, range
);
4836 if(sheet
->state
!= GTK_SHEET_NORMAL
){
4837 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
4838 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4839 if(GTK_SHEET_IN_RESIZE(sheet
) || GTK_SHEET_IN_DRAG(sheet
))
4840 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->drag_range
);
4842 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
4843 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
4844 if(GTK_SHEET_IN_RESIZE(sheet
) || GTK_SHEET_IN_DRAG(sheet
))
4845 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4848 if((!GTK_SHEET_IN_XDRAG(sheet
)) && (!GTK_SHEET_IN_YDRAG(sheet
))){
4849 if(sheet
->state
== GTK_SHEET_NORMAL
){
4850 gtk_sheet_draw_active_cell(sheet
);
4851 if(!GTK_SHEET_IN_SELECTION(sheet
))
4852 gtk_widget_queue_draw(sheet
->sheet_entry
);
4861 if(sheet
->state
!= GTK_SHEET_NORMAL
&& GTK_SHEET_IN_SELECTION(sheet
))
4862 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4864 (* GTK_WIDGET_CLASS (parent_class
)->expose_event
) (widget
, event
);
4867 printf("<--- Leaving gtk_sheet_expose\n");
4875 gtk_sheet_button_press (GtkWidget
* widget
,
4876 GdkEventButton
* event
)
4879 GdkModifierType mods
;
4880 gint x
, y
, row
, column
;
4883 g_return_val_if_fail (widget
!= NULL
, FALSE
);
4884 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
4885 g_return_val_if_fail (event
!= NULL
, FALSE
);
4887 if(event
->type
!= GDK_BUTTON_PRESS
) return TRUE
;
4888 gdk_window_get_pointer(widget
->window
, NULL
, NULL
, &mods
);
4889 if(!(mods
& GDK_BUTTON1_MASK
)) return TRUE
;
4891 sheet
= GTK_SHEET (widget
);
4893 /* press on resize windows */
4894 if (event
->window
== sheet
->column_title_window
&&
4895 gtk_sheet_columns_resizable(sheet
))
4897 gtk_widget_get_pointer (widget
, &sheet
->x_drag
, NULL
);
4898 if(POSSIBLE_XDRAG(sheet
, sheet
->x_drag
, &sheet
->drag_cell
.col
)){
4900 gtk_sheet_column_size_request(sheet
, sheet
->drag_cell
.col
, &req
);
4901 GTK_SHEET_SET_FLAGS (sheet
, GTK_SHEET_IN_XDRAG
);
4902 gdk_pointer_grab (sheet
->column_title_window
, FALSE
,
4903 GDK_POINTER_MOTION_HINT_MASK
|
4904 GDK_BUTTON1_MOTION_MASK
|
4905 GDK_BUTTON_RELEASE_MASK
,
4906 NULL
, NULL
, event
->time
);
4908 draw_xor_vline (sheet
);
4913 if (event
->window
== sheet
->row_title_window
&& gtk_sheet_rows_resizable(sheet
))
4915 gtk_widget_get_pointer (widget
, NULL
, &sheet
->y_drag
);
4917 if(POSSIBLE_YDRAG(sheet
, sheet
->y_drag
, &sheet
->drag_cell
.row
)){
4919 gtk_sheet_row_size_request(sheet
, sheet
->drag_cell
.row
, &req
);
4920 GTK_SHEET_SET_FLAGS (sheet
, GTK_SHEET_IN_YDRAG
);
4921 gdk_pointer_grab (sheet
->row_title_window
, FALSE
,
4922 GDK_POINTER_MOTION_HINT_MASK
|
4923 GDK_BUTTON1_MOTION_MASK
|
4924 GDK_BUTTON_RELEASE_MASK
,
4925 NULL
, NULL
, event
->time
);
4927 draw_xor_hline (sheet
);
4932 /* selections on the sheet */
4933 if(event
->window
== sheet
->sheet_window
){
4934 gtk_widget_get_pointer (widget
, &x
, &y
);
4935 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
4936 gdk_pointer_grab (sheet
->sheet_window
, FALSE
,
4937 GDK_POINTER_MOTION_HINT_MASK
|
4938 GDK_BUTTON1_MOTION_MASK
|
4939 GDK_BUTTON_RELEASE_MASK
,
4940 NULL
, NULL
, event
->time
);
4941 gtk_grab_add(GTK_WIDGET(sheet
));
4942 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
4943 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
4944 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
4945 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4947 if(sheet
->selection_mode
!= GTK_SELECTION_SINGLE
&&
4948 sheet
->cursor_drag
->type
==GDK_SIZING
&&
4949 !GTK_SHEET_IN_SELECTION(sheet
) && !GTK_SHEET_IN_RESIZE(sheet
)){
4950 if(sheet
->state
==GTK_STATE_NORMAL
) {
4951 row
=sheet
->active_cell
.row
;
4952 column
=sheet
->active_cell
.col
;
4953 if(!gtk_sheet_deactivate_cell(sheet
)) return FALSE
;
4954 sheet
->active_cell
.row
=row
;
4955 sheet
->active_cell
.col
=column
;
4956 sheet
->drag_range
=sheet
->range
;
4957 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
4958 gtk_sheet_select_range(sheet
, &sheet
->drag_range
);
4962 if(row
> sheet
->range
.rowi
) row
--;
4963 if(column
> sheet
->range
.coli
) column
--;
4964 sheet
->drag_cell
.row
= row
;
4965 sheet
->drag_cell
.col
= column
;
4966 sheet
->drag_range
=sheet
->range
;
4967 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4968 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_RESIZE
);
4970 else if(sheet
->cursor_drag
->type
==GDK_TOP_LEFT_ARROW
&&
4971 !GTK_SHEET_IN_SELECTION(sheet
) && !GTK_SHEET_IN_DRAG(sheet
)) {
4972 if(sheet
->state
==GTK_STATE_NORMAL
) {
4973 row
=sheet
->active_cell
.row
;
4974 column
=sheet
->active_cell
.col
;
4975 if(!gtk_sheet_deactivate_cell(sheet
)) return FALSE
;
4976 sheet
->active_cell
.row
=row
;
4977 sheet
->active_cell
.col
=column
;
4978 sheet
->drag_range
=sheet
->range
;
4979 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
4980 gtk_sheet_select_range(sheet
, &sheet
->drag_range
);
4984 if(row
< sheet
->range
.row0
) row
++;
4985 if(row
> sheet
->range
.rowi
) row
--;
4986 if(column
< sheet
->range
.col0
) column
++;
4987 if(column
> sheet
->range
.coli
) column
--;
4988 sheet
->drag_cell
.row
=row
;
4989 sheet
->drag_cell
.col
=column
;
4990 sheet
->drag_range
=sheet
->range
;
4991 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4992 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_DRAG
);
4996 gtk_sheet_click_cell(sheet
, row
, column
, &veto
);
4997 if(veto
) GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5002 if(event
->window
== sheet
->column_title_window
){
5003 gtk_widget_get_pointer (widget
, &x
, &y
);
5004 column
= COLUMN_FROM_XPIXEL(sheet
, x
);
5005 if(sheet
->column
[column
].is_sensitive
){;
5006 gtk_sheet_click_cell(sheet
, -1, column
, &veto
);
5007 gtk_grab_add(GTK_WIDGET(sheet
));
5008 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
5009 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
5010 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
5011 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5012 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5016 if(event
->window
== sheet
->row_title_window
){
5017 gtk_widget_get_pointer (widget
, &x
, &y
);
5018 row
= ROW_FROM_YPIXEL(sheet
, y
);
5019 if(sheet
->row
[row
].is_sensitive
){
5020 gtk_sheet_click_cell(sheet
, row
, -1, &veto
);
5021 gtk_grab_add(GTK_WIDGET(sheet
));
5022 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
5023 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
5024 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
5025 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5026 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5034 gtk_sheet_scroll(gpointer data
)
5037 gint x
,y
,row
,column
;
5040 sheet
=GTK_SHEET(data
);
5042 GDK_THREADS_ENTER();
5044 gtk_widget_get_pointer (GTK_WIDGET(sheet
), &x
, &y
);
5045 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
5049 if(GTK_SHEET_IN_SELECTION(sheet
))
5050 gtk_sheet_extend_selection(sheet
, row
, column
);
5052 if(GTK_SHEET_IN_DRAG(sheet
) || GTK_SHEET_IN_RESIZE(sheet
)){
5053 move
=gtk_sheet_move_query(sheet
, row
, column
);
5054 if(move
) draw_xor_rectangle(sheet
, sheet
->drag_range
);
5057 GDK_THREADS_LEAVE();
5064 gtk_sheet_click_cell(GtkSheet
*sheet
, gint row
, gint column
, gboolean
*veto
)
5068 if(row
> sheet
->maxrow
|| column
> sheet
->maxcol
){
5073 if(column
>= 0 && row
>= 0)
5074 if(!sheet
->column
[column
].is_visible
|| !sheet
->row
[row
].is_visible
)
5080 _gtkextra_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[TRAVERSE
],
5081 sheet
->active_cell
.row
, sheet
->active_cell
.col
,
5082 &row
, &column
, veto
);
5085 if(sheet
->state
== GTK_STATE_NORMAL
) return;
5087 row
= sheet
->active_cell
.row
;
5088 column
= sheet
->active_cell
.col
;
5089 gtk_sheet_activate_cell(sheet
, row
, column
);
5093 if(row
== -1 && column
>= 0){
5094 if(gtk_sheet_autoscroll(sheet
))
5095 gtk_sheet_move_query(sheet
, row
, column
);
5096 gtk_sheet_select_column(sheet
, column
);
5099 if(column
== -1 && row
>= 0){
5100 if(gtk_sheet_autoscroll(sheet
))
5101 gtk_sheet_move_query(sheet
, row
, column
);
5102 gtk_sheet_select_row(sheet
, row
);
5106 if(row
==-1 && column
==-1){
5107 sheet
->range
.row0
=0;
5108 sheet
->range
.col0
=0;
5109 sheet
->range
.rowi
=sheet
->maxrow
;
5110 sheet
->range
.coli
=sheet
->maxcol
;
5111 sheet
->active_cell
.row
=0;
5112 sheet
->active_cell
.col
=0;
5113 gtk_sheet_select_range(sheet
, NULL
);
5117 if(row
!=-1 && column
!=-1){
5118 if(sheet
->state
!= GTK_SHEET_NORMAL
){
5119 sheet
->state
= GTK_SHEET_NORMAL
;
5120 gtk_sheet_real_unselect_range(sheet
, NULL
);
5124 if(!gtk_sheet_deactivate_cell(sheet
)){
5130 if(gtk_sheet_autoscroll(sheet
))
5131 gtk_sheet_move_query(sheet
, row
, column
);
5132 sheet
->active_cell
.row
=row
;
5133 sheet
->active_cell
.col
=column
;
5134 sheet
->selection_cell
.row
=row
;
5135 sheet
->selection_cell
.col
=column
;
5136 sheet
->range
.row0
=row
;
5137 sheet
->range
.col0
=column
;
5138 sheet
->range
.rowi
=row
;
5139 sheet
->range
.coli
=column
;
5140 sheet
->state
=GTK_SHEET_NORMAL
;
5141 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5142 gtk_sheet_draw_active_cell(sheet
);
5146 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5147 sheet
->active_cell
.col
);
5151 gtk_sheet_button_release (GtkWidget
* widget
,
5152 GdkEventButton
* event
)
5157 sheet
=GTK_SHEET(widget
);
5159 /* release on resize windows */
5160 if (GTK_SHEET_IN_XDRAG (sheet
)){
5161 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_XDRAG
);
5162 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_SELECTION
);
5163 gtk_widget_get_pointer (widget
, &x
, NULL
);
5164 gdk_pointer_ungrab (event
->time
);
5165 draw_xor_vline (sheet
);
5167 gtk_sheet_set_column_width (sheet
, sheet
->drag_cell
.col
, new_column_width (sheet
, sheet
->drag_cell
.col
, &x
));
5168 sheet
->old_hadjustment
= -1.;
5169 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
), "value_changed");
5173 if (GTK_SHEET_IN_YDRAG (sheet
)){
5174 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_YDRAG
);
5175 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_SELECTION
);
5176 gtk_widget_get_pointer (widget
, NULL
, &y
);
5177 gdk_pointer_ungrab (event
->time
);
5178 draw_xor_hline (sheet
);
5180 gtk_sheet_set_row_height (sheet
, sheet
->drag_cell
.row
, new_row_height (sheet
, sheet
->drag_cell
.row
, &y
));
5181 sheet
->old_vadjustment
= -1.;
5182 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
), "value_changed");
5187 if (GTK_SHEET_IN_DRAG(sheet
)){
5188 GtkSheetRange old_range
;
5189 draw_xor_rectangle(sheet
, sheet
->drag_range
);
5190 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_DRAG
);
5191 gdk_pointer_ungrab (event
->time
);
5193 gtk_sheet_real_unselect_range(sheet
, NULL
);
5195 sheet
->active_cell
.row
= sheet
->active_cell
.row
+
5196 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5197 sheet
->active_cell
.col
= sheet
->active_cell
.col
+
5198 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5199 sheet
->selection_cell
.row
= sheet
->selection_cell
.row
+
5200 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5201 sheet
->selection_cell
.col
= sheet
->selection_cell
.col
+
5202 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5203 old_range
=sheet
->range
;
5204 sheet
->range
=sheet
->drag_range
;
5205 sheet
->drag_range
=old_range
;
5206 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[MOVE_RANGE
],
5207 &sheet
->drag_range
, &sheet
->range
);
5208 gtk_sheet_select_range(sheet
, &sheet
->range
);
5211 if (GTK_SHEET_IN_RESIZE(sheet
)){
5212 GtkSheetRange old_range
;
5213 draw_xor_rectangle(sheet
, sheet
->drag_range
);
5214 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_RESIZE
);
5215 gdk_pointer_ungrab (event
->time
);
5217 gtk_sheet_real_unselect_range(sheet
, NULL
);
5219 sheet
->active_cell
.row
= sheet
->active_cell
.row
+
5220 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5221 sheet
->active_cell
.col
= sheet
->active_cell
.col
+
5222 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5223 if(sheet
->drag_range
.row0
< sheet
->range
.row0
)
5224 sheet
->selection_cell
.row
= sheet
->drag_range
.row0
;
5225 if(sheet
->drag_range
.rowi
>= sheet
->range
.rowi
)
5226 sheet
->selection_cell
.row
= sheet
->drag_range
.rowi
;
5227 if(sheet
->drag_range
.col0
< sheet
->range
.col0
)
5228 sheet
->selection_cell
.col
= sheet
->drag_range
.col0
;
5229 if(sheet
->drag_range
.coli
>= sheet
->range
.coli
)
5230 sheet
->selection_cell
.col
= sheet
->drag_range
.coli
;
5231 old_range
= sheet
->range
;
5232 sheet
->range
= sheet
->drag_range
;
5233 sheet
->drag_range
= old_range
;
5235 if(sheet
->state
==GTK_STATE_NORMAL
) sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5236 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[RESIZE_RANGE
],
5237 &sheet
->drag_range
, &sheet
->range
);
5238 gtk_sheet_select_range(sheet
, &sheet
->range
);
5241 if(sheet
->state
== GTK_SHEET_NORMAL
&& GTK_SHEET_IN_SELECTION(sheet
)){
5242 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5243 gdk_pointer_ungrab (event
->time
);
5244 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5245 sheet
->active_cell
.col
);
5248 if(GTK_SHEET_IN_SELECTION
)
5249 gdk_pointer_ungrab (event
->time
);
5251 gtk_timeout_remove(sheet
->timer
);
5252 gtk_grab_remove(GTK_WIDGET(sheet
));
5254 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5260 gtk_sheet_motion (GtkWidget
* widget
,
5261 GdkEventMotion
* event
)
5264 GdkModifierType mods
;
5265 GdkCursorType new_cursor
;
5266 gint x
, y
, row
, column
;
5268 g_return_val_if_fail (widget
!= NULL
, FALSE
);
5269 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
5270 g_return_val_if_fail (event
!= NULL
, FALSE
);
5273 sheet
= GTK_SHEET (widget
);
5276 /* selections on the sheet */
5280 if(event
->window
== sheet
->column_title_window
&& gtk_sheet_columns_resizable(sheet
)){
5281 gtk_widget_get_pointer(widget
, &x
, &y
);
5282 if(!GTK_SHEET_IN_SELECTION(sheet
) && POSSIBLE_XDRAG(sheet
, x
, &column
)){
5283 new_cursor
=GDK_SB_H_DOUBLE_ARROW
;
5284 if(new_cursor
!= sheet
->cursor_drag
->type
){
5285 gdk_cursor_destroy(sheet
->cursor_drag
);
5286 sheet
->cursor_drag
=gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW
);
5287 gdk_window_set_cursor(sheet
->column_title_window
,sheet
->cursor_drag
);
5290 new_cursor
=GDK_TOP_LEFT_ARROW
;
5291 if(!GTK_SHEET_IN_XDRAG(sheet
) && new_cursor
!= sheet
->cursor_drag
->type
){
5292 gdk_cursor_destroy(sheet
->cursor_drag
);
5293 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5294 gdk_window_set_cursor(sheet
->column_title_window
,sheet
->cursor_drag
);
5299 if(event
->window
== sheet
->row_title_window
&& gtk_sheet_rows_resizable(sheet
)){
5300 gtk_widget_get_pointer(widget
, &x
, &y
);
5301 if(!GTK_SHEET_IN_SELECTION(sheet
) && POSSIBLE_YDRAG(sheet
,y
, &column
)){
5302 new_cursor
=GDK_SB_V_DOUBLE_ARROW
;
5303 if(new_cursor
!= sheet
->cursor_drag
->type
){
5304 gdk_cursor_destroy(sheet
->cursor_drag
);
5305 sheet
->cursor_drag
=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW
);
5306 gdk_window_set_cursor(sheet
->row_title_window
,sheet
->cursor_drag
);
5309 new_cursor
=GDK_TOP_LEFT_ARROW
;
5310 if(!GTK_SHEET_IN_YDRAG(sheet
) && new_cursor
!= sheet
->cursor_drag
->type
){
5311 gdk_cursor_destroy(sheet
->cursor_drag
);
5312 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5313 gdk_window_set_cursor(sheet
->row_title_window
,sheet
->cursor_drag
);
5318 new_cursor
=GDK_PLUS
;
5319 if(!POSSIBLE_DRAG(sheet
,x
,y
,&row
,&column
) && !GTK_SHEET_IN_DRAG(sheet
) &&
5320 !POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) && !GTK_SHEET_IN_RESIZE(sheet
) &&
5321 event
->window
== sheet
->sheet_window
&&
5322 new_cursor
!= sheet
->cursor_drag
->type
){
5323 gdk_cursor_destroy(sheet
->cursor_drag
);
5324 sheet
->cursor_drag
=gdk_cursor_new(GDK_PLUS
);
5325 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5328 new_cursor
=GDK_TOP_LEFT_ARROW
;
5329 if(!(POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) || GTK_SHEET_IN_RESIZE(sheet
)) &&
5330 (POSSIBLE_DRAG(sheet
, x
,y
,&row
,&column
) || GTK_SHEET_IN_DRAG(sheet
)) &&
5331 event
->window
== sheet
->sheet_window
&&
5332 new_cursor
!= sheet
->cursor_drag
->type
){
5333 gdk_cursor_destroy(sheet
->cursor_drag
);
5334 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5335 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5338 new_cursor
=GDK_SIZING
;
5339 if(!GTK_SHEET_IN_DRAG(sheet
) &&
5340 (POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) || GTK_SHEET_IN_RESIZE(sheet
)) &&
5341 event
->window
== sheet
->sheet_window
&&
5342 new_cursor
!= sheet
->cursor_drag
->type
){
5343 gdk_cursor_destroy(sheet
->cursor_drag
);
5344 sheet
->cursor_drag
=gdk_cursor_new(GDK_SIZING
);
5345 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5348 gdk_window_get_pointer (widget
->window
, &x
, &y
, &mods
);
5349 if(!(mods
& GDK_BUTTON1_MASK
)) return FALSE
;
5351 if (GTK_SHEET_IN_XDRAG (sheet
)){
5352 if (event
->is_hint
|| event
->window
!= widget
->window
)
5353 gtk_widget_get_pointer (widget
, &x
, NULL
);
5357 new_column_width (sheet
, sheet
->drag_cell
.col
, &x
);
5358 if (x
!= sheet
->x_drag
)
5360 draw_xor_vline (sheet
);
5362 draw_xor_vline (sheet
);
5367 if (GTK_SHEET_IN_YDRAG (sheet
)){
5368 if (event
->is_hint
|| event
->window
!= widget
->window
)
5369 gtk_widget_get_pointer (widget
, NULL
, &y
);
5373 new_row_height (sheet
, sheet
->drag_cell
.row
, &y
);
5374 if (y
!= sheet
->y_drag
)
5376 draw_xor_hline (sheet
);
5378 draw_xor_hline (sheet
);
5383 if (GTK_SHEET_IN_DRAG(sheet
)){
5385 column
=COLUMN_FROM_XPIXEL(sheet
,x
)-sheet
->drag_cell
.col
;
5386 row
=ROW_FROM_YPIXEL(sheet
,y
)-sheet
->drag_cell
.row
;
5387 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) row
=0;
5388 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) column
=0;
5392 if(aux
.row0
+row
>= 0 && aux
.rowi
+row
<= sheet
->maxrow
&&
5393 aux
.col0
+column
>= 0 && aux
.coli
+column
<= sheet
->maxcol
){
5394 aux
=sheet
->drag_range
;
5395 sheet
->drag_range
.row0
=sheet
->range
.row0
+row
;
5396 sheet
->drag_range
.col0
=sheet
->range
.col0
+column
;
5397 sheet
->drag_range
.rowi
=sheet
->range
.rowi
+row
;
5398 sheet
->drag_range
.coli
=sheet
->range
.coli
+column
;
5399 if(aux
.row0
!= sheet
->drag_range
.row0
||
5400 aux
.col0
!= sheet
->drag_range
.col0
){
5401 draw_xor_rectangle (sheet
, aux
);
5402 draw_xor_rectangle (sheet
, sheet
->drag_range
);
5408 if (GTK_SHEET_IN_RESIZE(sheet
)){
5412 if(abs(x
-COLUMN_LEFT_XPIXEL(sheet
,sheet
->drag_cell
.col
)) >
5413 abs(y
-ROW_TOP_YPIXEL(sheet
,sheet
->drag_cell
.row
))) v_h
=2;
5415 column
=COLUMN_FROM_XPIXEL(sheet
,x
)-sheet
->drag_cell
.col
;
5416 row
=ROW_FROM_YPIXEL(sheet
,y
)-sheet
->drag_cell
.row
;
5417 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) row
=0;
5418 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) column
=0;
5423 if(row
< sheet
->range
.row0
- sheet
->range
.rowi
- 1)
5424 row
=row
+(sheet
->range
.rowi
-sheet
->range
.row0
+ 1);
5425 else if(row
<0) row
=0;
5427 if(column
< sheet
->range
.col0
- sheet
->range
.coli
- 1)
5428 column
=column
+(sheet
->range
.coli
-sheet
->range
.col0
+ 1);
5429 else if(column
<0) column
=0;
5436 if(aux
.row0
+row
>= 0 && aux
.rowi
+row
<= sheet
->maxrow
&&
5437 aux
.col0
+column
>= 0 && aux
.coli
+column
<= sheet
->maxcol
){
5439 aux
=sheet
->drag_range
;
5440 sheet
->drag_range
=sheet
->range
;
5442 if(row
<0) sheet
->drag_range
.row0
=sheet
->range
.row0
+row
;
5443 if(row
>0) sheet
->drag_range
.rowi
=sheet
->range
.rowi
+row
;
5444 if(column
<0) sheet
->drag_range
.col0
=sheet
->range
.col0
+column
;
5445 if(column
>0) sheet
->drag_range
.coli
=sheet
->range
.coli
+column
;
5447 if(aux
.row0
!= sheet
->drag_range
.row0
||
5448 aux
.rowi
!= sheet
->drag_range
.rowi
||
5449 aux
.col0
!= sheet
->drag_range
.col0
||
5450 aux
.coli
!= sheet
->drag_range
.coli
){
5451 draw_xor_rectangle (sheet
, aux
);
5452 draw_xor_rectangle (sheet
, sheet
->drag_range
);
5460 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
5462 if(sheet
->state
==GTK_SHEET_NORMAL
&& row
==sheet
->active_cell
.row
&&
5463 column
==sheet
->active_cell
.col
) return TRUE
;
5465 if(GTK_SHEET_IN_SELECTION(sheet
) && mods
&GDK_BUTTON1_MASK
)
5466 gtk_sheet_extend_selection(sheet
, row
, column
);
5472 gtk_sheet_move_query(GtkSheet
*sheet
, gint row
, gint column
)
5474 gint row_move
, column_move
;
5475 gfloat row_align
, col_align
;
5476 guint height
, width
;
5478 gint new_col
= column
;
5485 height
= sheet
->sheet_window_height
;
5486 width
= sheet
->sheet_window_width
;
5488 if(row
>=MAX_VISIBLE_ROW(sheet
) && sheet
->state
!=GTK_SHEET_COLUMN_SELECTED
) {
5490 new_row
= MIN(sheet
->maxrow
, row
+ 1);
5492 if(MAX_VISIBLE_ROW(sheet
) == sheet
->maxrow
&&
5493 ROW_TOP_YPIXEL(sheet
, sheet
->maxrow
) +
5494 sheet
->row
[sheet
->maxrow
].height
< height
){
5499 if(row
<MIN_VISIBLE_ROW(sheet
) && sheet
->state
!=GTK_SHEET_COLUMN_SELECTED
) {
5503 if(column
>=MAX_VISIBLE_COLUMN(sheet
) && sheet
->state
!=GTK_SHEET_ROW_SELECTED
) {
5505 new_col
= MIN(sheet
->maxcol
, column
+ 1);
5507 if(MAX_VISIBLE_COLUMN(sheet
) == sheet
->maxcol
&&
5508 COLUMN_LEFT_XPIXEL(sheet
, sheet
->maxcol
) +
5509 sheet
->column
[sheet
->maxcol
].width
< width
){
5510 column_move
= FALSE
;
5514 if(column
<MIN_VISIBLE_COLUMN(sheet
) && sheet
->state
!=GTK_SHEET_ROW_SELECTED
) {
5519 if(row_move
|| column_move
){
5520 gtk_sheet_moveto(sheet
, new_row
, new_col
, row_align
, col_align
);
5523 return(row_move
|| column_move
);
5527 gtk_sheet_extend_selection(GtkSheet
*sheet
, gint row
, gint column
)
5529 GtkSheetRange range
;
5533 if(row
== sheet
->selection_cell
.row
&& column
== sheet
->selection_cell
.col
)
5536 if(sheet
->selection_mode
== GTK_SELECTION_SINGLE
) return;
5538 gtk_sheet_move_query(sheet
, row
, column
);
5539 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5541 if(GTK_SHEET_IN_DRAG(sheet
)) return;
5545 switch(sheet
->state
){
5546 case GTK_SHEET_ROW_SELECTED
:
5547 column
= sheet
->maxcol
;
5549 case GTK_SHEET_COLUMN_SELECTED
:
5550 row
= sheet
->maxrow
;
5552 case GTK_SHEET_NORMAL
:
5553 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5554 r
=sheet
->active_cell
.row
;
5555 c
=sheet
->active_cell
.col
;
5556 sheet
->range
.col0
=c
;
5557 sheet
->range
.row0
=r
;
5558 sheet
->range
.coli
=c
;
5559 sheet
->range
.rowi
=r
;
5560 gdk_draw_pixmap(sheet
->sheet_window
,
5561 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
5563 COLUMN_LEFT_XPIXEL(sheet
,c
)-1,
5564 ROW_TOP_YPIXEL(sheet
,r
)-1,
5565 COLUMN_LEFT_XPIXEL(sheet
,c
)-1,
5566 ROW_TOP_YPIXEL(sheet
,r
)-1,
5567 sheet
->column
[c
].width
+4,
5568 sheet
->row
[r
].height
+4);
5569 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
5570 case GTK_SHEET_RANGE_SELECTED
:
5571 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5574 sheet
->selection_cell
.row
= row
;
5575 sheet
->selection_cell
.col
= column
;
5577 range
.col0
=MIN(column
,sheet
->active_cell
.col
);
5578 range
.coli
=MAX(column
,sheet
->active_cell
.col
);
5579 range
.row0
=MIN(row
,sheet
->active_cell
.row
);
5580 range
.rowi
=MAX(row
,sheet
->active_cell
.row
);
5582 if(range
.row0
!= sheet
->range
.row0
|| range
.rowi
!= sheet
->range
.rowi
||
5583 range
.col0
!= sheet
->range
.col0
|| range
.coli
!= sheet
->range
.coli
||
5584 state
==GTK_SHEET_NORMAL
)
5585 gtk_sheet_real_select_range(sheet
, &range
);
5589 /* Removed by SDB while cleaning up key press behavior */
5592 gtk_sheet_entry_key_press(GtkWidget
*widget
,
5597 printf("Entered gtk_sheet_entry_key_press. . . . . \n");
5600 gtk_signal_emit_by_name(GTK_OBJECT(widget
), "key_press_event", key
, &focus
);
5606 gtk_sheet_key_press(GtkWidget
*widget
,
5612 gboolean extend_selection
= FALSE
;
5614 gboolean force_move
= FALSE
;
5616 gboolean in_selection
= FALSE
;
5617 gboolean veto
= TRUE
;
5620 sheet
= GTK_SHEET(widget
);
5623 printf("\n\nJust entered gtk_sheet_key_press. . . . \n");
5627 if(key
->state
& GDK_CONTROL_MASK
|| key
->keyval
==GDK_Control_L
||
5628 key
->keyval
==GDK_Control_R
) return FALSE
;
5632 if(key->keyval=='c' || key->keyval == 'C' && sheet->state != GTK_STATE_NORMAL)
5633 gtk_sheet_clip_range(sheet, sheet->range);
5634 if(key->keyval=='x' || key->keyval == 'X')
5635 gtk_sheet_unclip_range(sheet);
5640 /* extend_selection is set when shift, ctrl, etc is pressed & held down */
5641 extend_selection
= (key
->state
& GDK_SHIFT_MASK
) || key
->keyval
==GDK_Shift_L
5642 || key
->keyval
==GDK_Shift_R
;
5645 printf(". . . . extend_selection = %d\n", extend_selection
);
5649 in_selection
= GTK_SHEET_IN_SELECTION(sheet
);
5650 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5653 printf("We are about to enter the switch statement. . .\n");
5656 switch(key
->keyval
){
5657 case GDK_Return
: case GDK_KP_Enter
:
5658 if(sheet
->state
== GTK_SHEET_NORMAL
&&
5659 !GTK_SHEET_IN_SELECTION(sheet
))
5660 gtk_signal_emit_stop_by_name(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
5662 row
= sheet
->active_cell
.row
;
5663 col
= sheet
->active_cell
.col
;
5664 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5665 row
= MIN_VISIBLE_ROW(sheet
)-1;
5666 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5667 col
= MIN_VISIBLE_COLUMN(sheet
);
5668 if(row
< sheet
->maxrow
){
5670 while(!sheet
->row
[row
].is_visible
&& row
<sheet
->maxrow
) row
++;
5672 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5673 extend_selection
= FALSE
;
5676 case GDK_ISO_Left_Tab
:
5677 case GDK_Left
: /* Left arrow */
5679 printf("In gtk_sheet_key_press, received GDK_Left.\n");
5681 row
= sheet
->active_cell
.row
;
5682 col
= sheet
->active_cell
.col
;
5683 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5684 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5685 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5686 row
= MIN_VISIBLE_ROW(sheet
);
5689 while(!sheet
->column
[col
].is_visible
&& col
>0) col
--;
5692 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5693 extend_selection
= FALSE
;
5697 case GDK_Right
: /* Right arrow */
5699 printf("In gtk_sheet_key_press, received GDK_Right.\n");
5701 row
= sheet
->active_cell
.row
;
5702 col
= sheet
->active_cell
.col
;
5703 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5704 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5705 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5706 row
= MIN_VISIBLE_ROW(sheet
);
5707 if(col
< sheet
->maxcol
){
5709 while(!sheet
->column
[col
].is_visible
&& col
<sheet
->maxcol
) col
++;
5711 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5712 extend_selection
= FALSE
;
5715 /* case GDK_BackSpace:
5716 if(sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0){
5717 if(sheet->active_cell.col > 0){
5718 col = sheet->active_cell.col - scroll;
5719 row = sheet->active_cell.row;
5720 while(!sheet->column[col].is_visible && col > 0) col--;
5723 gtk_sheet_click_cell(sheet, row, col, &veto);
5724 extend_selection = FALSE;
5729 scroll
=MAX_VISIBLE_ROW(sheet
)-MIN_VISIBLE_ROW(sheet
)+1;
5730 case GDK_Up
: /* arrow key up */
5731 if(extend_selection
){
5732 if(state
==GTK_STATE_NORMAL
){
5733 row
=sheet
->active_cell
.row
;
5734 col
=sheet
->active_cell
.col
;
5735 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5738 if(sheet
->selection_cell
.row
> 0){
5739 row
= sheet
->selection_cell
.row
- scroll
;
5740 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5742 gtk_sheet_extend_selection(sheet
, row
, sheet
->selection_cell
.col
);
5746 col
= sheet
->active_cell
.col
;
5747 row
= sheet
->active_cell
.row
;
5748 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5749 row
= MIN_VISIBLE_ROW(sheet
);
5750 if(state
==GTK_SHEET_ROW_SELECTED
)
5751 col
= MIN_VISIBLE_COLUMN(sheet
);
5753 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5755 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5756 extend_selection
= FALSE
;
5760 scroll
=MAX_VISIBLE_ROW(sheet
)-MIN_VISIBLE_ROW(sheet
)+1;
5761 case GDK_Down
: /* arrow key down */
5762 if(extend_selection
){
5763 if(state
==GTK_STATE_NORMAL
){
5764 row
=sheet
->active_cell
.row
;
5765 col
=sheet
->active_cell
.col
;
5766 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5769 if(sheet
->selection_cell
.row
< sheet
->maxrow
){
5770 row
= sheet
->selection_cell
.row
+ scroll
;
5771 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5772 row
= MIN(sheet
->maxrow
, row
);
5773 gtk_sheet_extend_selection(sheet
, row
, sheet
->selection_cell
.col
);
5777 col
= sheet
->active_cell
.col
;
5778 row
= sheet
->active_cell
.row
;
5779 if(sheet
->active_cell
.row
< sheet
->maxrow
){
5780 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5781 row
= MIN_VISIBLE_ROW(sheet
)-1;
5782 if(state
==GTK_SHEET_ROW_SELECTED
)
5783 col
= MIN_VISIBLE_COLUMN(sheet
);
5785 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5786 row
= MIN(sheet
->maxrow
, row
);
5788 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5789 extend_selection
= FALSE
;
5794 if(extend_selection
){
5795 if(state
==GTK_STATE_NORMAL
){
5796 row
=sheet
->active_cell
.row
;
5797 col
=sheet
->active_cell
.col
;
5798 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5801 if(sheet
->selection_cell
.col
< sheet
->maxcol
){
5802 col
= sheet
->selection_cell
.col
+ 1;
5803 while(!sheet
->column
[col
].is_visible
&& col
< sheet
->maxcol
) col
++;
5804 gtk_sheet_extend_selection(sheet
, sheet
->selection_cell
.row
, col
);
5808 col
= sheet
->active_cell
.col
;
5809 row
= sheet
->active_cell
.row
;
5810 if(sheet
->active_cell
.col
< sheet
->maxcol
){
5812 if(state
==GTK_SHEET_ROW_SELECTED
)
5813 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5814 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5815 row
= MIN_VISIBLE_ROW(sheet
);
5816 while(!sheet
->column
[col
].is_visible
&& col
< sheet
->maxcol
) col
++;
5817 if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)))) == 0
5819 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5824 extend_selection
= FALSE
;
5829 if(extend_selection
){
5830 if(state
==GTK_STATE_NORMAL
){
5831 row
=sheet
->active_cell
.row
;
5832 col
=sheet
->active_cell
.col
;
5833 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5836 if(sheet
->selection_cell
.col
> 0){
5837 col
= sheet
->selection_cell
.col
- 1;
5838 while(!sheet
->column
[col
].is_visible
&& col
> 0) col
--;
5839 gtk_sheet_extend_selection(sheet
, sheet
->selection_cell
.row
, col
);
5843 col
= sheet
->active_cell
.col
- 1;
5844 row
= sheet
->active_cell
.row
;
5845 if(state
==GTK_SHEET_ROW_SELECTED
)
5846 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5847 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5848 row
= MIN_VISIBLE_ROW(sheet
);
5849 while(!sheet
->column
[col
].is_visible
&& col
> 0) col
--;
5852 if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)))) == 0
5854 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5858 extend_selection
= FALSE
;
5865 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5866 gtk_sheet_click_cell(sheet
, row
, sheet
->active_cell
.col
, &veto
);
5867 extend_selection
= FALSE
;
5872 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5873 gtk_sheet_click_cell(sheet
, row
, sheet
->active_cell
.col
, &veto
);
5874 extend_selection
= FALSE
;
5879 printf("In gtk_sheet_key_press, after switch, found default case.\n");
5880 printf(" User probably typed letter key or DEL.\n");
5882 sheet_head
->CHANGED
= 1; /* cell has been updated. */
5884 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5885 if(extend_selection
) return TRUE
;
5887 if(state
== GTK_SHEET_ROW_SELECTED
)
5888 sheet
->active_cell
.col
=MIN_VISIBLE_COLUMN(sheet
);
5889 if(state
== GTK_SHEET_COLUMN_SELECTED
)
5890 sheet
->active_cell
.row
=MIN_VISIBLE_ROW(sheet
);
5894 if(extend_selection
) return TRUE
;
5896 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5897 sheet
->active_cell
.col
);
5903 gtk_sheet_size_request (GtkWidget
* widget
,
5904 GtkRequisition
* requisition
)
5908 GtkSheetChild
*child
;
5909 GtkRequisition child_requisition
;
5911 g_return_if_fail (widget
!= NULL
);
5912 g_return_if_fail (GTK_IS_SHEET (widget
));
5913 g_return_if_fail (requisition
!= NULL
);
5915 sheet
= GTK_SHEET (widget
);
5917 requisition
->width
= 3*DEFAULT_COLUMN_WIDTH
;
5918 requisition
->height
= 3*DEFAULT_ROW_HEIGHT(widget
);
5920 /* compute the size of the column title area */
5921 if(sheet
->column_titles_visible
)
5922 requisition
->height
+= sheet
->column_title_area
.height
;
5924 /* compute the size of the row title area */
5925 if(sheet
->row_titles_visible
)
5926 requisition
->width
+= sheet
->row_title_area
.width
;
5928 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
5929 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
5930 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
5931 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
5933 if(!sheet
->column_titles_visible
)
5934 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
5936 if(!sheet
->row_titles_visible
)
5937 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
5939 children
= sheet
->children
;
5942 child
= children
->data
;
5943 children
= g_list_next(children
);
5945 gtk_widget_size_request(child
->widget
, &child_requisition
);
5951 gtk_sheet_size_allocate (GtkWidget
* widget
,
5952 GtkAllocation
* allocation
)
5955 GtkAllocation sheet_allocation
;
5958 g_return_if_fail (widget
!= NULL
);
5959 g_return_if_fail (GTK_IS_SHEET (widget
));
5960 g_return_if_fail (allocation
!= NULL
);
5962 sheet
= GTK_SHEET (widget
);
5963 widget
->allocation
= *allocation
;
5964 border_width
= GTK_CONTAINER(widget
)->border_width
;
5966 if (GTK_WIDGET_REALIZED (widget
))
5967 gdk_window_move_resize (widget
->window
,
5968 allocation
->x
+ border_width
,
5969 allocation
->y
+ border_width
,
5970 allocation
->width
- 2*border_width
,
5971 allocation
->height
- 2*border_width
);
5973 /* use internal allocation structure for all the math
5974 * because it's easier than always subtracting the container
5976 sheet
->internal_allocation
.x
= 0;
5977 sheet
->internal_allocation
.y
= 0;
5978 sheet
->internal_allocation
.width
= allocation
->width
- 2*border_width
;
5979 sheet
->internal_allocation
.height
= allocation
->height
- 2*border_width
;
5981 sheet_allocation
.x
= 0;
5982 sheet_allocation
.y
= 0;
5983 sheet_allocation
.width
= allocation
->width
- 2*border_width
;
5984 sheet_allocation
.height
= allocation
->height
- 2*border_width
;
5986 sheet
->sheet_window_width
= sheet_allocation
.width
;
5987 sheet
->sheet_window_height
= sheet_allocation
.height
;
5989 if (GTK_WIDGET_REALIZED (widget
))
5990 gdk_window_move_resize (sheet
->sheet_window
,
5993 sheet_allocation
.width
,
5994 sheet_allocation
.height
);
5996 /* position the window which holds the column title buttons */
5997 sheet
->column_title_area
.x
= 0;
5998 sheet
->column_title_area
.y
= 0;
5999 if(sheet
->row_titles_visible
)
6000 sheet
->column_title_area
.x
= sheet
->row_title_area
.width
;
6001 sheet
->column_title_area
.width
= sheet_allocation
.width
-
6002 sheet
->column_title_area
.x
;
6003 if(GTK_WIDGET_REALIZED(widget
) && sheet
->column_titles_visible
)
6004 gdk_window_move_resize (sheet
->column_title_window
,
6005 sheet
->column_title_area
.x
,
6006 sheet
->column_title_area
.y
,
6007 sheet
->column_title_area
.width
,
6008 sheet
->column_title_area
.height
);
6010 sheet
->sheet_window_width
= sheet_allocation
.width
;
6011 sheet
->sheet_window_height
= sheet_allocation
.height
;
6013 /* column button allocation */
6014 size_allocate_column_title_buttons (sheet
);
6016 /* position the window which holds the row title buttons */
6017 sheet
->row_title_area
.x
= 0;
6018 sheet
->row_title_area
.y
= 0;
6019 if(sheet
->column_titles_visible
)
6020 sheet
->row_title_area
.y
= sheet
->column_title_area
.height
;
6021 sheet
->row_title_area
.height
= sheet_allocation
.height
-
6022 sheet
->row_title_area
.y
;
6024 if(GTK_WIDGET_REALIZED(widget
) && sheet
->row_titles_visible
)
6025 gdk_window_move_resize (sheet
->row_title_window
,
6026 sheet
->row_title_area
.x
,
6027 sheet
->row_title_area
.y
,
6028 sheet
->row_title_area
.width
,
6029 sheet
->row_title_area
.height
);
6032 /* row button allocation */
6033 size_allocate_row_title_buttons (sheet
);
6035 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
6036 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
6037 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
6038 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
6040 if(!sheet
->column_titles_visible
)
6041 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
6043 if(!sheet
->row_titles_visible
)
6044 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
6046 size_allocate_column_title_buttons(sheet
);
6047 size_allocate_row_title_buttons(sheet
);
6049 /* re-scale backing pixmap */
6050 gtk_sheet_make_backing_pixmap(sheet
, 0, 0);
6051 gtk_sheet_position_children(sheet
);
6053 /* set the scrollbars adjustments */
6054 adjust_scrollbars (sheet
);
6058 size_allocate_column_title_buttons (GtkSheet
* sheet
)
6063 if (!sheet
->column_titles_visible
) return;
6064 if (!GTK_WIDGET_REALIZED (sheet
))
6067 width
= sheet
->sheet_window_width
;
6070 if(sheet
->row_titles_visible
)
6072 width
-= sheet
->row_title_area
.width
;
6073 x
= sheet
->row_title_area
.width
;
6076 if(sheet
->column_title_area
.width
!= width
|| sheet
->column_title_area
.x
!= x
)
6078 sheet
->column_title_area
.width
= width
;
6079 sheet
->column_title_area
.x
= x
;
6080 gdk_window_move_resize (sheet
->column_title_window
,
6081 sheet
->column_title_area
.x
,
6082 sheet
->column_title_area
.y
,
6083 sheet
->column_title_area
.width
,
6084 sheet
->column_title_area
.height
);
6088 if(MAX_VISIBLE_COLUMN(sheet
) == sheet
->maxcol
)
6089 gdk_window_clear_area (sheet
->column_title_window
,
6091 sheet
->column_title_area
.width
,
6092 sheet
->column_title_area
.height
);
6094 if(!GTK_WIDGET_DRAWABLE(sheet
)) return;
6096 for (i
= MIN_VISIBLE_COLUMN(sheet
); i
<= MAX_VISIBLE_COLUMN(sheet
); i
++)
6097 gtk_sheet_button_draw(sheet
,-1,i
);
6101 size_allocate_row_title_buttons (GtkSheet
* sheet
)
6106 if (!sheet
->row_titles_visible
) return;
6107 if (!GTK_WIDGET_REALIZED (sheet
))
6110 height
= sheet
->sheet_window_height
;
6113 if(sheet
->column_titles_visible
)
6115 height
-= sheet
->column_title_area
.height
;
6116 y
= sheet
->column_title_area
.height
;
6119 if(sheet
->row_title_area
.height
!= height
|| sheet
->row_title_area
.y
!= y
){
6120 sheet
->row_title_area
.y
= y
;
6121 sheet
->row_title_area
.height
= height
;
6122 gdk_window_move_resize (sheet
->row_title_window
,
6123 sheet
->row_title_area
.x
,
6124 sheet
->row_title_area
.y
,
6125 sheet
->row_title_area
.width
,
6126 sheet
->row_title_area
.height
);
6128 if(MAX_VISIBLE_ROW(sheet
) == sheet
->maxrow
)
6129 gdk_window_clear_area (sheet
->row_title_window
,
6131 sheet
->row_title_area
.width
,
6132 sheet
->row_title_area
.height
);
6134 if(!GTK_WIDGET_DRAWABLE(sheet
)) return;
6136 for(i
= MIN_VISIBLE_ROW(sheet
); i
<= MAX_VISIBLE_ROW(sheet
); i
++)
6137 gtk_sheet_button_draw(sheet
,i
,-1);
6141 gtk_sheet_recalc_top_ypixels(GtkSheet
*sheet
, gint row
)
6145 cy
= sheet
->column_title_area
.height
;
6146 if(!sheet
->column_titles_visible
) cy
= 0;
6147 for(i
=0; i
<=sheet
->maxrow
; i
++){
6148 sheet
->row
[i
].top_ypixel
=cy
;
6149 if(sheet
->row
[i
].is_visible
) cy
+=sheet
->row
[i
].height
;
6154 gtk_sheet_recalc_left_xpixels(GtkSheet
*sheet
, gint column
)
6158 cx
= sheet
->row_title_area
.width
;
6159 if(!sheet
->row_titles_visible
) cx
= 0;
6160 for(i
=0; i
<=sheet
->maxcol
; i
++){
6161 sheet
->column
[i
].left_xpixel
=cx
;
6162 if(sheet
->column
[i
].is_visible
) cx
+=sheet
->column
[i
].width
;
6170 gtk_sheet_size_allocate_entry(GtkSheet
*sheet
)
6172 GtkAllocation shentry_allocation
;
6173 GtkSheetCellAttr attributes
;
6174 GtkEntry
*sheet_entry
;
6175 GtkStyle
*style
= NULL
, *previous_style
= NULL
;
6177 gint size
, max_size
, text_size
, column_width
;
6180 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
6181 if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
))) return;
6183 sheet_entry
= GTK_ENTRY(gtk_sheet_get_entry(sheet
));
6185 gtk_sheet_get_attributes(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
, &attributes
);
6187 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
)){
6189 if(!GTK_WIDGET(sheet_entry
)->style
)
6190 gtk_widget_ensure_style(GTK_WIDGET(sheet_entry
));
6192 previous_style
= GTK_WIDGET(sheet_entry
)->style
;
6194 style
= gtk_style_copy(previous_style
);
6195 style
->bg
[GTK_STATE_NORMAL
] = attributes
.background
;
6196 style
->fg
[GTK_STATE_NORMAL
] = attributes
.foreground
;
6197 style
->text
[GTK_STATE_NORMAL
] = attributes
.foreground
;
6198 style
->bg
[GTK_STATE_ACTIVE
] = attributes
.background
;
6199 style
->fg
[GTK_STATE_ACTIVE
] = attributes
.foreground
;
6200 style
->text
[GTK_STATE_ACTIVE
] = attributes
.foreground
;
6202 pango_font_description_free(style
->font_desc
);
6203 style
->font_desc
= pango_font_description_copy(attributes
.font_desc
);
6205 GTK_WIDGET(sheet_entry
)->style
= style
;
6206 gtk_widget_size_request(sheet
->sheet_entry
, NULL
);
6207 GTK_WIDGET(sheet_entry
)->style
= previous_style
;
6209 if(style
!= previous_style
){
6210 if(!GTK_IS_ITEM_ENTRY(sheet
->sheet_entry
)){
6211 style
->bg
[GTK_STATE_NORMAL
] = previous_style
->bg
[GTK_STATE_NORMAL
];
6212 style
->fg
[GTK_STATE_NORMAL
] = previous_style
->fg
[GTK_STATE_NORMAL
];
6213 style
->bg
[GTK_STATE_ACTIVE
] = previous_style
->bg
[GTK_STATE_ACTIVE
];
6214 style
->fg
[GTK_STATE_ACTIVE
] = previous_style
->fg
[GTK_STATE_ACTIVE
];
6216 gtk_widget_set_style(GTK_WIDGET(sheet_entry
), style
);
6220 if(GTK_IS_ITEM_ENTRY(sheet_entry
))
6221 max_size
= GTK_ITEM_ENTRY(sheet_entry
)->text_max_size
;
6226 text
= gtk_entry_get_text(GTK_ENTRY(sheet_entry
));
6227 if(text
&& strlen(text
) > 0){
6228 text_size
= STRING_WIDTH(GTK_WIDGET(sheet
), attributes
.font_desc
, text
);
6231 column_width
=sheet
->column
[sheet
->active_cell
.col
].width
;
6233 size
=MIN(text_size
, max_size
);
6234 size
=MAX(size
,column_width
-2*CELLOFFSET
);
6236 row
=sheet
->active_cell
.row
;
6237 col
=sheet
->active_cell
.col
;
6239 shentry_allocation
.x
= COLUMN_LEFT_XPIXEL(sheet
,sheet
->active_cell
.col
);
6240 shentry_allocation
.y
= ROW_TOP_YPIXEL(sheet
,sheet
->active_cell
.row
);
6241 shentry_allocation
.width
= column_width
;
6242 shentry_allocation
.height
= sheet
->row
[sheet
->active_cell
.row
].height
;
6244 if(GTK_IS_ITEM_ENTRY(sheet
->sheet_entry
)){
6246 shentry_allocation
.height
-= 2*CELLOFFSET
;
6247 shentry_allocation
.y
+= CELLOFFSET
;
6248 if(gtk_sheet_clip_text(sheet
))
6249 shentry_allocation
.width
= column_width
- 2*CELLOFFSET
;
6251 shentry_allocation
.width
= size
;
6253 switch(GTK_ITEM_ENTRY(sheet_entry
)->justification
){
6254 case GTK_JUSTIFY_CENTER
:
6255 shentry_allocation
.x
+= (column_width
)/2 - size
/2;
6257 case GTK_JUSTIFY_RIGHT
:
6258 shentry_allocation
.x
+= column_width
- size
- CELLOFFSET
;
6260 case GTK_JUSTIFY_LEFT
:
6261 case GTK_JUSTIFY_FILL
:
6262 shentry_allocation
.x
+= CELLOFFSET
;
6268 if(!GTK_IS_ITEM_ENTRY(sheet
->sheet_entry
)){
6269 shentry_allocation
.x
+= 2;
6270 shentry_allocation
.y
+= 2;
6271 shentry_allocation
.width
-= MIN(shentry_allocation
.width
, 3);
6272 shentry_allocation
.height
-= MIN(shentry_allocation
.height
, 3);
6275 gtk_widget_size_allocate(sheet
->sheet_entry
, &shentry_allocation
);
6277 if(previous_style
== style
) gtk_style_unref(previous_style
);
6281 gtk_sheet_entry_set_max_size(GtkSheet
*sheet
)
6285 gint sizel
=0, sizer
=0;
6287 GtkJustification justification
;
6289 row
=sheet
->active_cell
.row
;
6290 col
=sheet
->active_cell
.col
;
6292 if(!GTK_IS_ITEM_ENTRY(sheet
->sheet_entry
) || gtk_sheet_clip_text(sheet
)) return;
6295 justification
= GTK_ITEM_ENTRY(sheet
->sheet_entry
)->justification
;
6297 switch(justification
){
6298 case GTK_JUSTIFY_FILL
:
6299 case GTK_JUSTIFY_LEFT
:
6300 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
6301 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
6302 size
+=sheet
->column
[i
].width
;
6304 size
= MIN(size
, sheet
->sheet_window_width
- COLUMN_LEFT_XPIXEL(sheet
, col
));
6306 case GTK_JUSTIFY_RIGHT
:
6307 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
6308 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
6309 size
+=sheet
->column
[i
].width
;
6312 case GTK_JUSTIFY_CENTER
:
6313 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
6314 /* if(gtk_sheet_cell_get_text(sheet, row, i)) break;
6316 sizer
+=sheet
->column
[i
].width
;
6318 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
6319 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
6320 sizel
+=sheet
->column
[i
].width
;
6322 size
=2*MIN(sizel
, sizer
);
6326 if(size
!=0) size
+=sheet
->column
[col
].width
;
6327 GTK_ITEM_ENTRY(sheet
->sheet_entry
)->text_max_size
=size
;
6332 create_sheet_entry(GtkSheet
*sheet
)
6338 gint found_entry
= FALSE
;
6340 widget
= GTK_WIDGET(sheet
);
6342 style
= gtk_style_copy(GTK_WIDGET(sheet
)->style
);
6344 if(sheet
->sheet_entry
){
6345 /* avoids warnings */
6346 gtk_widget_ref(sheet
->sheet_entry
);
6347 gtk_widget_unparent(sheet
->sheet_entry
);
6348 gtk_widget_destroy(sheet
->sheet_entry
);
6351 if(sheet
->entry_type
){
6353 if(!gtk_type_is_a (sheet
->entry_type
, GTK_TYPE_ENTRY
)){
6355 parent
= GTK_WIDGET(gtk_type_new(sheet
->entry_type
));
6357 sheet
->sheet_entry
= parent
;
6359 entry
= gtk_sheet_get_entry (sheet
);
6360 if(GTK_IS_ENTRY(entry
)) found_entry
= TRUE
;
6364 parent
= GTK_WIDGET(gtk_type_new(sheet
->entry_type
));
6372 g_warning ("Entry type must be GtkEntry subclass, using default");
6373 entry
= gtk_item_entry_new();
6374 sheet
->sheet_entry
= entry
;
6378 sheet
->sheet_entry
= parent
;
6385 entry
= gtk_item_entry_new();
6386 sheet
->sheet_entry
= entry
;
6390 gtk_widget_size_request(sheet
->sheet_entry
, NULL
);
6392 if(GTK_WIDGET_REALIZED(sheet
))
6394 gtk_widget_set_parent_window (sheet
->sheet_entry
, sheet
->sheet_window
);
6395 gtk_widget_set_parent(sheet
->sheet_entry
, GTK_WIDGET(sheet
));
6396 gtk_widget_realize(sheet
->sheet_entry
);
6400 /* SDB says: I need to work out the event passing system */
6401 gtk_signal_connect_object(GTK_OBJECT(entry
),"key_press_event",
6402 (GtkSignalFunc
) gtk_sheet_key_press
,
6404 /* gtk_signal_connect_object(GTK_OBJECT(entry),"key_press_event",
6405 (GtkSignalFunc) gtk_sheet_entry_key_press,
6410 gtk_widget_show (sheet
->sheet_entry
);
6415 gtk_sheet_get_entry(GtkSheet
*sheet
)
6418 GtkWidget
*entry
= NULL
;
6419 GtkTableChild
*table_child
;
6420 GtkBoxChild
*box_child
;
6421 GList
*children
= NULL
;
6423 g_return_val_if_fail (sheet
!= NULL
, NULL
);
6424 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
6425 g_return_val_if_fail (sheet
->sheet_entry
!= NULL
, NULL
);
6427 if(GTK_IS_ENTRY(sheet
->sheet_entry
)) return (sheet
->sheet_entry
);
6429 parent
= GTK_WIDGET(sheet
->sheet_entry
);
6431 if(GTK_IS_TABLE(parent
)) children
= GTK_TABLE(parent
)->children
;
6432 if(GTK_IS_BOX(parent
)) children
= GTK_BOX(parent
)->children
;
6434 if(!children
) return NULL
;
6437 if(GTK_IS_TABLE(parent
)) {
6438 table_child
= children
->data
;
6439 entry
= table_child
->widget
;
6441 if(GTK_IS_BOX(parent
)){
6442 box_child
= children
->data
;
6443 entry
= box_child
->widget
;
6446 if(GTK_IS_ENTRY(entry
))
6448 children
= g_list_next(children
);
6452 if(!GTK_IS_ENTRY(entry
)) return NULL
;
6459 gtk_sheet_get_entry_widget(GtkSheet
*sheet
)
6461 g_return_val_if_fail (sheet
!= NULL
, NULL
);
6462 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
6463 g_return_val_if_fail (sheet
->sheet_entry
!= NULL
, NULL
);
6465 return (sheet
->sheet_entry
);
6470 row_button_set (GtkSheet
*sheet
, gint row
)
6472 if(sheet
->row
[row
].button
.state
== GTK_STATE_ACTIVE
) return;
6474 sheet
->row
[row
].button
.state
= GTK_STATE_ACTIVE
;
6475 gtk_sheet_button_draw(sheet
, row
, -1);
6480 column_button_set (GtkSheet
*sheet
, gint column
)
6482 if(sheet
->column
[column
].button
.state
== GTK_STATE_ACTIVE
) return;
6484 sheet
->column
[column
].button
.state
= GTK_STATE_ACTIVE
;
6485 gtk_sheet_button_draw(sheet
, -1, column
);
6490 row_button_release (GtkSheet
*sheet
, gint row
)
6492 if(sheet
->row
[row
].button
.state
== GTK_STATE_NORMAL
) return;
6494 sheet
->row
[row
].button
.state
= GTK_STATE_NORMAL
;
6495 gtk_sheet_button_draw(sheet
, row
, -1);
6499 column_button_release (GtkSheet
*sheet
, gint column
)
6501 if(sheet
->column
[column
].button
.state
== GTK_STATE_NORMAL
) return;
6503 sheet
->column
[column
].button
.state
= GTK_STATE_NORMAL
;
6504 gtk_sheet_button_draw(sheet
, -1, column
);
6508 gtk_sheet_button_draw (GtkSheet
*sheet
, gint row
, gint column
)
6510 GdkWindow
*window
= NULL
;
6511 GtkShadowType shadow_type
;
6512 guint width
= 0, height
= 0;
6515 gint text_width
= 0, text_height
= 0;
6516 GtkSheetButton
*button
= NULL
;
6517 GtkSheetChild
*child
= NULL
;
6518 GdkRectangle allocation
;
6519 gboolean is_sensitive
= FALSE
;
6526 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
6528 if(row
>= 0 && !sheet
->row
[row
].is_visible
) return;
6529 if(column
>= 0 && !sheet
->column
[column
].is_visible
) return;
6530 if(row
>= 0 && !sheet
->row_titles_visible
) return;
6531 if(column
>= 0 && !sheet
->column_titles_visible
) return;
6532 if(column
>=0 && column
<MIN_VISIBLE_COLUMN(sheet
)) return;
6533 if(column
>=0 && column
>MAX_VISIBLE_COLUMN(sheet
)) return;
6534 if(row
>=0 && row
<MIN_VISIBLE_ROW(sheet
)) return;
6535 if(row
>=0 && row
>MAX_VISIBLE_ROW(sheet
)) return;
6536 if( (row
== -1) && (column
== -1) ) return;
6539 window
=sheet
->column_title_window
;
6540 button
=&sheet
->column
[column
].button
;
6542 x
= COLUMN_LEFT_XPIXEL(sheet
, column
)+CELL_SPACING
;
6543 if(sheet
->row_titles_visible
) x
-= sheet
->row_title_area
.width
;
6545 width
= sheet
->column
[column
].width
;
6546 height
= sheet
->column_title_area
.height
;
6547 is_sensitive
=sheet
->column
[column
].is_sensitive
;
6549 else if(column
==-1){
6550 window
=sheet
->row_title_window
;
6551 button
=&sheet
->row
[row
].button
;
6554 y
= ROW_TOP_YPIXEL(sheet
, row
)+CELL_SPACING
;
6555 if(sheet
->column_titles_visible
) y
-=sheet
->column_title_area
.height
;
6556 width
= sheet
->row_title_area
.width
;
6557 height
= sheet
->row
[row
].height
;
6558 is_sensitive
=sheet
->row
[row
].is_sensitive
;
6563 allocation
.width
= width
;
6564 allocation
.height
= height
;
6566 gdk_window_clear_area (window
,
6570 gtk_paint_box (sheet
->button
->style
, window
,
6571 GTK_STATE_NORMAL
, GTK_SHADOW_OUT
,
6572 &allocation
, GTK_WIDGET(sheet
),
6573 "buttondefault", x
, y
, width
, height
);
6575 state
= button
->state
;
6576 if(!is_sensitive
) state
=GTK_STATE_INSENSITIVE
;
6578 if (state
== GTK_STATE_ACTIVE
)
6579 shadow_type
= GTK_SHADOW_IN
;
6581 shadow_type
= GTK_SHADOW_OUT
;
6583 if(state
!= GTK_STATE_NORMAL
&& state
!= GTK_STATE_INSENSITIVE
)
6584 gtk_paint_box (sheet
->button
->style
, window
,
6585 button
->state
, shadow_type
,
6586 &allocation
, GTK_WIDGET(sheet
),
6587 "button", x
, y
, width
, height
);
6589 if(button
->label_visible
){
6591 text_height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))-2*CELLOFFSET
;
6593 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->fg_gc
[button
->state
],
6595 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->white_gc
, &allocation
);
6597 y
+= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))/2 + sheet
->button
->style
->ythickness
+ DEFAULT_FONT_DESCENT(GTK_WIDGET(sheet
));
6599 if(button
->label
&& strlen(button
->label
)>0){
6601 words
=button
->label
;
6602 line
= g_new(gchar
, 1);
6605 while(words
&& *words
!= '\0'){
6608 line
=g_realloc(line
, len
+2);
6612 if(*words
== '\n' || *(words
+1) == '\0'){
6613 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, line
);
6615 switch(button
->justification
){
6616 case GTK_JUSTIFY_LEFT
:
6617 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6618 &allocation
, GTK_WIDGET(sheet
), "label",
6622 case GTK_JUSTIFY_RIGHT
:
6623 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6624 &allocation
, GTK_WIDGET(sheet
), "label",
6625 x
+ width
- text_width
- CELLOFFSET
, y
,
6628 case GTK_JUSTIFY_CENTER
:
6630 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6631 &allocation
, GTK_WIDGET(sheet
), "label",
6632 x
+ (width
- text_width
) /2, y
,
6636 y
+= text_height
+ 2;
6639 line
= g_new(gchar
, 1);
6646 sprintf(label
,"%d",index
);
6647 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, label
);
6649 switch(button
->justification
){
6650 case GTK_JUSTIFY_LEFT
:
6651 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6652 &allocation
, GTK_WIDGET(sheet
), "label",
6656 case GTK_JUSTIFY_RIGHT
:
6657 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6658 &allocation
, GTK_WIDGET(sheet
), "label",
6659 x
+ width
- text_width
- CELLOFFSET
, y
,
6662 case GTK_JUSTIFY_CENTER
:
6664 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6665 &allocation
, GTK_WIDGET(sheet
), "label",
6666 x
+ (width
- text_width
) /2, y
,
6672 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->fg_gc
[button
->state
],
6674 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->white_gc
, NULL
);
6678 if((child
= button
->child
) && (child
->widget
)){
6679 child
->x
= allocation
.x
;
6680 child
->y
= allocation
.y
;
6682 child
->x
+= (width
- child
->widget
->requisition
.width
) / 2;
6683 child
->y
+= (height
- child
->widget
->requisition
.height
) / 2;
6684 allocation
.x
= child
->x
;
6685 allocation
.y
= child
->y
;
6686 allocation
.width
= child
->widget
->requisition
.width
;
6687 allocation
.height
= child
->widget
->requisition
.height
;
6692 gtk_widget_set_state(child
->widget
, button
->state
);
6694 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
6695 GTK_WIDGET_MAPPED(child
->widget
))
6697 gtk_widget_size_allocate(child
->widget
,
6699 gtk_widget_queue_draw(child
->widget
);
6710 * vadjustment_changed
6711 * hadjustment_changed
6712 * vadjustment_value_changed
6713 * hadjustment_value_changed */
6716 adjust_scrollbars (GtkSheet
* sheet
)
6719 if(sheet
->vadjustment
){
6720 sheet
->vadjustment
->page_size
= sheet
->sheet_window_height
;
6721 sheet
->vadjustment
->page_increment
= sheet
->sheet_window_height
/ 2;
6722 sheet
->vadjustment
->step_increment
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
6723 sheet
->vadjustment
->lower
= 0;
6724 sheet
->vadjustment
->upper
= SHEET_HEIGHT (sheet
) + 80;
6726 if (sheet->sheet_window_height - sheet->voffset > SHEET_HEIGHT (sheet))
6728 sheet->vadjustment->value = MAX(0, SHEET_HEIGHT (sheet) -
6729 sheet->sheet_window_height);
6730 gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment),
6734 gtk_signal_emit_by_name (GTK_OBJECT(sheet
->vadjustment
), "changed");
6738 if(sheet
->hadjustment
){
6739 sheet
->hadjustment
->page_size
= sheet
->sheet_window_width
;
6740 sheet
->hadjustment
->page_increment
= sheet
->sheet_window_width
/ 2;
6741 sheet
->hadjustment
->step_increment
= DEFAULT_COLUMN_WIDTH
;
6742 sheet
->hadjustment
->lower
= 0;
6743 sheet
->hadjustment
->upper
= SHEET_WIDTH (sheet
)+ 80;
6745 if (sheet->sheet_window_width - sheet->hoffset > SHEET_WIDTH (sheet))
6747 sheet->hadjustment->value = MAX(0, SHEET_WIDTH (sheet) -
6748 sheet->sheet_window_width);
6749 gtk_signal_emit_by_name (GTK_OBJECT(sheet->hadjustment),
6753 gtk_signal_emit_by_name (GTK_OBJECT(sheet
->hadjustment
), "changed");
6757 if(GTK_WIDGET_REALIZED(sheet))
6759 if(sheet->row_titles_visible){
6760 size_allocate_row_title_buttons(sheet);
6761 gdk_window_show(sheet->row_title_window);
6764 if(sheet->column_titles_visible){
6765 size_allocate_column_title_buttons(sheet);
6766 gdk_window_show(sheet->column_title_window);
6769 gtk_sheet_range_draw(sheet, NULL);
6776 vadjustment_changed (GtkAdjustment
* adjustment
,
6781 g_return_if_fail (adjustment
!= NULL
);
6782 g_return_if_fail (data
!= NULL
);
6784 sheet
= GTK_SHEET (data
);
6789 hadjustment_changed (GtkAdjustment
* adjustment
,
6794 g_return_if_fail (adjustment
!= NULL
);
6795 g_return_if_fail (data
!= NULL
);
6797 sheet
= GTK_SHEET (data
);
6803 vadjustment_value_changed (GtkAdjustment
* adjustment
,
6807 gint diff
, value
, old_value
;
6812 g_return_if_fail (adjustment
!= NULL
);
6813 g_return_if_fail (data
!= NULL
);
6814 g_return_if_fail (GTK_IS_SHEET (data
));
6816 sheet
= GTK_SHEET (data
);
6818 if(GTK_SHEET_IS_FROZEN(sheet
)) return;
6820 row
=ROW_FROM_YPIXEL(sheet
,sheet
->column_title_area
.height
+ CELL_SPACING
);
6821 if(!sheet
->column_titles_visible
)
6822 row
=ROW_FROM_YPIXEL(sheet
,CELL_SPACING
);
6824 old_value
= -sheet
->voffset
;
6826 for(i
=0; i
<= sheet
->maxrow
; i
++){
6827 if(sheet
->row
[i
].is_visible
) y
+=sheet
->row
[i
].height
;
6828 if(y
> adjustment
->value
) break;
6830 y
-=sheet
->row
[i
].height
;
6833 if (adjustment
->value
> sheet
->old_vadjustment
&& sheet
->old_vadjustment
> 0. &&
6834 sheet
->row
[i
].height
> sheet
->vadjustment
->step_increment
){
6835 /* This avoids embarrassing twitching */
6836 if(row
== new_row
&& row
!= sheet
->maxrow
&&
6837 adjustment
->value
- sheet
->old_vadjustment
>=
6838 sheet
->vadjustment
->step_increment
&&
6839 new_row
+ 1 != MIN_VISIBLE_ROW(sheet
)){
6841 y
=y
+sheet
->row
[row
].height
;
6845 /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
6846 if(sheet
->old_vadjustment
>= 0. && row
== new_row
){
6847 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
6851 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
6852 adjustment
->value
=y
;
6856 sheet
->vadjustment
->step_increment
=
6857 sheet
->row
[0].height
;
6859 sheet
->vadjustment
->step_increment
=
6860 MIN(sheet
->row
[new_row
].height
, sheet
->row
[new_row
-1].height
);
6863 sheet
->vadjustment
->value
=adjustment
->value
;
6865 value
= adjustment
->value
;
6867 if (value
>= -sheet
->voffset
)
6870 diff
= value
+ sheet
->voffset
;
6875 diff
= -sheet
->voffset
- value
;
6878 sheet
->voffset
= -value
;
6880 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
6881 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
6882 if(!sheet
->column_titles_visible
)
6883 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
6885 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
) &&
6886 sheet
->state
== GTK_SHEET_NORMAL
&&
6887 sheet
->active_cell
.row
>= 0 && sheet
->active_cell
.col
>= 0 &&
6888 !gtk_sheet_cell_isvisible(sheet
, sheet
->active_cell
.row
,
6889 sheet
->active_cell
.col
))
6893 text
= gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
6895 if(!text
|| strlen(text
)==0)
6896 gtk_sheet_cell_clear(sheet
,
6897 sheet
->active_cell
.row
,
6898 sheet
->active_cell
.col
);
6899 gtk_widget_unmap(sheet
->sheet_entry
);
6902 gtk_sheet_position_children(sheet
);
6904 gtk_sheet_range_draw(sheet
, NULL
);
6905 size_allocate_row_title_buttons(sheet
);
6906 size_allocate_global_button(sheet
);
6910 hadjustment_value_changed (GtkAdjustment
* adjustment
,
6914 gint i
, diff
, value
, old_value
;
6915 gint column
, new_column
;
6918 g_return_if_fail (adjustment
!= NULL
);
6919 g_return_if_fail (data
!= NULL
);
6920 g_return_if_fail (GTK_IS_SHEET (data
));
6922 sheet
= GTK_SHEET (data
);
6924 if(GTK_SHEET_IS_FROZEN(sheet
)) return;
6926 column
=COLUMN_FROM_XPIXEL(sheet
,sheet
->row_title_area
.width
+ CELL_SPACING
);
6927 if(!sheet
->row_titles_visible
)
6928 column
=COLUMN_FROM_XPIXEL(sheet
, CELL_SPACING
);
6930 old_value
= -sheet
->hoffset
;
6932 for(i
=0; i
<= sheet
->maxcol
; i
++){
6933 if(sheet
->column
[i
].is_visible
) x
+=sheet
->column
[i
].width
;
6934 if(x
> adjustment
->value
) break;
6936 x
-=sheet
->column
[i
].width
;
6939 if (adjustment
->value
> sheet
->old_hadjustment
&& sheet
->old_hadjustment
> 0 &&
6940 sheet
->column
[i
].width
> sheet
->hadjustment
->step_increment
){
6941 /* This avoids embarrassing twitching */
6942 if(column
== new_column
&& column
!= sheet
->maxcol
&&
6943 adjustment
->value
- sheet
->old_hadjustment
>=
6944 sheet
->hadjustment
->step_increment
&&
6945 new_column
+ 1 != MIN_VISIBLE_COLUMN(sheet
)){
6947 x
=x
+sheet
->column
[column
].width
;
6951 /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
6952 if(sheet
->old_hadjustment
>= 0. && new_column
== column
){
6953 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
6957 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
6958 adjustment
->value
=x
;
6960 if(new_column
== 0){
6961 sheet
->hadjustment
->step_increment
=
6962 sheet
->column
[0].width
;
6964 sheet
->hadjustment
->step_increment
=
6965 MIN(sheet
->column
[new_column
].width
, sheet
->column
[new_column
-1].width
);
6969 sheet
->hadjustment
->value
=adjustment
->value
;
6971 value
= adjustment
->value
;
6973 if (value
>= -sheet
->hoffset
)
6976 diff
= value
+ sheet
->hoffset
;
6981 diff
= -sheet
->hoffset
- value
;
6984 sheet
->hoffset
= -value
;
6986 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
6987 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
6988 if(!sheet
->row_titles_visible
)
6989 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
6991 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
) &&
6992 sheet
->state
== GTK_SHEET_NORMAL
&&
6993 sheet
->active_cell
.row
>= 0 && sheet
->active_cell
.col
>= 0 &&
6994 !gtk_sheet_cell_isvisible(sheet
, sheet
->active_cell
.row
,
6995 sheet
->active_cell
.col
))
6999 text
= gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
7000 if(!text
|| strlen(text
)==0)
7001 gtk_sheet_cell_clear(sheet
,
7002 sheet
->active_cell
.row
,
7003 sheet
->active_cell
.col
);
7005 gtk_widget_unmap(sheet
->sheet_entry
);
7008 gtk_sheet_position_children(sheet
);
7010 gtk_sheet_range_draw(sheet
, NULL
);
7011 size_allocate_column_title_buttons(sheet
);
7015 /* COLUMN RESIZING */
7017 draw_xor_vline (GtkSheet
* sheet
)
7021 g_return_if_fail (sheet
!= NULL
);
7023 widget
= GTK_WIDGET (sheet
);
7025 gdk_draw_line (widget
->window
, sheet
->xor_gc
,
7027 sheet
->column_title_area
.height
,
7029 sheet
->sheet_window_height
+ 1);
7034 draw_xor_hline (GtkSheet
* sheet
)
7038 g_return_if_fail (sheet
!= NULL
);
7040 widget
= GTK_WIDGET (sheet
);
7042 gdk_draw_line (widget
->window
, sheet
->xor_gc
,
7043 sheet
->row_title_area
.width
,
7046 sheet
->sheet_window_width
+ 1,
7050 /* SELECTED RANGE */
7052 draw_xor_rectangle(GtkSheet
*sheet
, GtkSheetRange range
)
7055 GdkRectangle clip_area
, area
;
7058 area
.x
=COLUMN_LEFT_XPIXEL(sheet
, range
.col0
);
7059 area
.y
=ROW_TOP_YPIXEL(sheet
, range
.row0
);
7060 area
.width
=COLUMN_LEFT_XPIXEL(sheet
, range
.coli
)-area
.x
+
7061 sheet
->column
[range
.coli
].width
;
7062 area
.height
=ROW_TOP_YPIXEL(sheet
, range
.rowi
)-area
.y
+
7063 sheet
->row
[range
.rowi
].height
;
7065 clip_area
.x
=sheet
->row_title_area
.width
;
7066 clip_area
.y
=sheet
->column_title_area
.height
;
7067 clip_area
.width
=sheet
->sheet_window_width
;
7068 clip_area
.height
=sheet
->sheet_window_height
;
7070 if(!sheet
->row_titles_visible
) clip_area
.x
= 0;
7071 if(!sheet
->column_titles_visible
) clip_area
.y
= 0;
7074 area
.width
=area
.width
+area
.x
;
7077 if(area
.width
>clip_area
.width
) area
.width
=clip_area
.width
+10;
7079 area
.height
=area
.height
+area
.y
;
7082 if(area
.height
>clip_area
.height
) area
.height
=clip_area
.height
+10;
7087 clip_area
.height
+=3;
7089 gdk_gc_get_values(sheet
->xor_gc
, &values
);
7091 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &clip_area
);
7094 gdk_draw_rectangle(sheet
->sheet_window
,
7098 area
.width
-2*i
, area
.height
-2*i
);
7101 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
7103 gdk_gc_set_foreground(sheet
->xor_gc
, &values
.foreground
);
7108 /* this function returns the new width of the column being resized given
7109 * the column and x position of the cursor; the x cursor position is passed
7110 * in as a pointer and automaticaly corrected if it's beyond min/max limits */
7112 new_column_width (GtkSheet
* sheet
,
7117 GtkRequisition requisition
;
7121 requisition
.width
= sheet
->column
[column
].requisition
;
7123 /* you can't shrink a column to less than its minimum width */
7124 if (cx
< COLUMN_LEFT_XPIXEL (sheet
, column
) + requisition
.width
)
7126 *x
= cx
= COLUMN_LEFT_XPIXEL (sheet
, column
) + requisition
.width
;
7129 /* don't grow past the end of the window */
7131 if (cx > sheet->sheet_window_width)
7133 *x = cx = sheet->sheet_window_width;
7136 /* calculate new column width making sure it doesn't end up
7137 * less than the minimum width */
7138 width
= cx
- COLUMN_LEFT_XPIXEL (sheet
, column
);
7139 if (width
< requisition
.width
)
7140 width
= requisition
.width
;
7142 sheet
->column
[column
].width
= width
;
7143 gtk_sheet_recalc_left_xpixels(sheet
, column
+1);
7144 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
7145 size_allocate_column_title_buttons (sheet
);
7150 /* this function returns the new height of the row being resized given
7151 * the row and y position of the cursor; the y cursor position is passed
7152 * in as a pointer and automaticaly corrected if it's beyond min/max limits */
7154 new_row_height (GtkSheet
* sheet
,
7158 GtkRequisition requisition
;
7163 requisition
.height
= sheet
->row
[row
].requisition
;
7165 /* you can't shrink a row to less than its minimum height */
7166 if (cy
< ROW_TOP_YPIXEL (sheet
, row
) + requisition
.height
)
7169 *y
= cy
= ROW_TOP_YPIXEL (sheet
, row
) + requisition
.height
;
7172 /* don't grow past the end of the window */
7174 if (cy > sheet->sheet_window_height)
7176 *y = cy = sheet->sheet_window_height;
7179 /* calculate new row height making sure it doesn't end up
7180 * less than the minimum height */
7181 height
= (cy
- ROW_TOP_YPIXEL (sheet
, row
));
7182 if (height
< requisition
.height
)
7183 height
= requisition
.height
;
7185 sheet
->row
[row
].height
= height
;
7186 gtk_sheet_recalc_top_ypixels(sheet
, row
);
7187 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
7188 size_allocate_row_title_buttons (sheet
);
7194 gtk_sheet_set_column_width (GtkSheet
* sheet
,
7200 g_return_if_fail (sheet
!= NULL
);
7201 g_return_if_fail (GTK_IS_SHEET (sheet
));
7203 if (column
< 0 || column
> sheet
->maxcol
)
7206 gtk_sheet_column_size_request(sheet
, column
, &min_width
);
7207 if(width
< min_width
) return;
7209 sheet
->column
[column
].width
= width
;
7211 gtk_sheet_recalc_left_xpixels(sheet
, column
+1);
7213 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) && !GTK_SHEET_IS_FROZEN(sheet
)){
7214 size_allocate_column_title_buttons (sheet
);
7215 adjust_scrollbars (sheet
);
7216 gtk_sheet_size_allocate_entry(sheet
);
7217 gtk_sheet_range_draw (sheet
, NULL
);
7220 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CHANGED
], -1, column
);
7221 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[NEW_COL_WIDTH
], column
, width
);
7226 gtk_sheet_set_row_height (GtkSheet
* sheet
,
7232 g_return_if_fail (sheet
!= NULL
);
7233 g_return_if_fail (GTK_IS_SHEET (sheet
));
7235 if (row
< 0 || row
> sheet
->maxrow
)
7238 gtk_sheet_row_size_request(sheet
, row
, &min_height
);
7239 if(height
< min_height
) return;
7241 sheet
->row
[row
].height
= height
;
7243 gtk_sheet_recalc_top_ypixels(sheet
, row
+1);
7245 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) && !GTK_SHEET_IS_FROZEN(sheet
)){
7246 size_allocate_row_title_buttons (sheet
);
7247 adjust_scrollbars (sheet
);
7248 gtk_sheet_size_allocate_entry(sheet
);
7249 gtk_sheet_range_draw (sheet
, NULL
);
7252 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CHANGED
], row
, -1);
7253 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[NEW_ROW_HEIGHT
], row
, height
);
7259 gtk_sheet_add_column(GtkSheet
*sheet
, guint ncols
)
7262 g_return_if_fail (sheet
!= NULL
);
7263 g_return_if_fail (GTK_IS_SHEET (sheet
));
7265 AddColumn(sheet
, ncols
);
7267 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7269 adjust_scrollbars(sheet
);
7271 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) sheet
->range
.coli
+=ncols
;
7273 sheet
->old_hadjustment
= -1.;
7274 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7275 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7280 gtk_sheet_add_row(GtkSheet
*sheet
, guint nrows
)
7283 g_return_if_fail (sheet
!= NULL
);
7284 g_return_if_fail (GTK_IS_SHEET (sheet
));
7286 AddRow(sheet
, nrows
);
7288 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7290 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) sheet
->range
.rowi
+=nrows
;
7292 adjust_scrollbars(sheet
);
7294 sheet
->old_vadjustment
= -1.;
7295 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7296 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7301 gtk_sheet_insert_rows(GtkSheet
*sheet
, guint row
, guint nrows
)
7304 GtkSheetChild
*child
;
7306 g_return_if_fail (sheet
!= NULL
);
7307 g_return_if_fail (GTK_IS_SHEET (sheet
));
7309 if(GTK_WIDGET_REALIZED(sheet
))
7310 gtk_sheet_real_unselect_range(sheet
, NULL
);
7312 InsertRow(sheet
, row
, nrows
);
7314 children
= sheet
->children
;
7317 child
= (GtkSheetChild
*)children
->data
;
7319 if(child
->attached_to_cell
)
7320 if(child
->row
>= row
) child
->row
+= nrows
;
7322 children
= g_list_next(children
);
7325 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7327 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) sheet
->range
.rowi
+=nrows
;
7328 adjust_scrollbars(sheet
);
7330 sheet
->old_vadjustment
= -1.;
7331 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7332 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7338 gtk_sheet_insert_columns(GtkSheet
*sheet
, guint col
, guint ncols
)
7341 GtkSheetChild
*child
;
7343 g_return_if_fail (sheet
!= NULL
);
7344 g_return_if_fail (GTK_IS_SHEET (sheet
));
7346 if(GTK_WIDGET_REALIZED(sheet
))
7347 gtk_sheet_real_unselect_range(sheet
, NULL
);
7349 InsertColumn(sheet
, col
, ncols
);
7351 children
= sheet
->children
;
7354 child
= (GtkSheetChild
*)children
->data
;
7356 if(child
->attached_to_cell
)
7357 if(child
->col
>= col
) child
->col
+= ncols
;
7359 children
= g_list_next(children
);
7362 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7364 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) sheet
->range
.coli
+=ncols
;
7365 adjust_scrollbars(sheet
);
7367 sheet
->old_hadjustment
= -1.;
7368 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7369 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7375 gtk_sheet_delete_rows(GtkSheet
*sheet
, guint row
, guint nrows
)
7378 GtkSheetChild
*child
;
7382 g_return_if_fail (sheet
!= NULL
);
7383 g_return_if_fail (GTK_IS_SHEET (sheet
));
7385 nrows
= MIN(nrows
, sheet
->maxrow
-row
+1);
7387 if(GTK_WIDGET_REALIZED(sheet
))
7388 gtk_sheet_real_unselect_range(sheet
, NULL
);
7390 DeleteRow(sheet
, row
, nrows
);
7392 children
= sheet
->children
;
7395 child
= (GtkSheetChild
*)children
->data
;
7397 if(child
->attached_to_cell
&&
7398 child
->row
>= row
&& child
->row
< row
+nrows
){
7399 gtk_container_remove(GTK_CONTAINER(sheet
), child
->widget
);
7400 children
= sheet
->children
;
7402 children
= g_list_next(children
);
7405 children
= sheet
->children
;
7408 child
= (GtkSheetChild
*)children
->data
;
7410 if(child
->attached_to_cell
&& child
->row
> row
) child
->row
-= nrows
;
7411 children
= g_list_next(children
);
7414 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7416 irow
= sheet
->active_cell
.row
;
7417 icol
= sheet
->active_cell
.col
;
7419 sheet
->active_cell
.row
= -1;
7420 sheet
->active_cell
.col
= -1;
7422 /* if(sheet->state == GTK_SHEET_ROW_SELECTED)
7425 irow
= MIN(irow
, sheet
->maxrow
);
7426 irow
= MAX(irow
, 0);
7427 gtk_sheet_click_cell(sheet
, irow
, icol
, &veto
);
7429 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
7430 sheet
->active_cell
.col
);
7432 adjust_scrollbars(sheet
);
7434 sheet
->old_vadjustment
= -1.;
7435 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7436 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7442 gtk_sheet_delete_columns(GtkSheet
*sheet
, guint col
, guint ncols
)
7445 GtkSheetChild
*child
;
7449 g_return_if_fail (sheet
!= NULL
);
7450 g_return_if_fail (GTK_IS_SHEET (sheet
));
7452 ncols
= MIN(ncols
, sheet
->maxcol
-col
+1);
7454 if(GTK_WIDGET_REALIZED(sheet
))
7455 gtk_sheet_real_unselect_range(sheet
, NULL
);
7457 DeleteColumn(sheet
, col
, ncols
);
7459 children
= sheet
->children
;
7462 child
= (GtkSheetChild
*)children
->data
;
7464 if(child
->attached_to_cell
&&
7465 child
->col
>= col
&& child
->col
< col
+ncols
){
7466 gtk_container_remove(GTK_CONTAINER(sheet
), child
->widget
);
7467 children
= sheet
->children
;
7469 children
= g_list_next(children
);
7472 children
= sheet
->children
;
7475 child
= (GtkSheetChild
*)children
->data
;
7477 if(child
->attached_to_cell
&& child
->col
> col
) child
->col
-= ncols
;
7478 children
= g_list_next(children
);
7481 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7483 irow
= sheet
->active_cell
.row
;
7484 icol
= sheet
->active_cell
.col
;
7486 sheet
->active_cell
.row
= -1;
7487 sheet
->active_cell
.col
= -1;
7489 /* if(sheet->state == GTK_SHEET_COLUMN_SELECTED)
7492 icol
= MIN(icol
, sheet
->maxcol
);
7493 icol
= MAX(icol
, 0);
7494 gtk_sheet_click_cell(sheet
, irow
, icol
, &veto
);
7496 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
7497 sheet
->active_cell
.col
);
7499 adjust_scrollbars(sheet
);
7501 sheet
->old_hadjustment
= -1.;
7502 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7503 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7509 gtk_sheet_range_set_background(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7512 GtkSheetCellAttr attributes
;
7513 GtkSheetRange range
;
7515 g_return_if_fail (sheet
!= NULL
);
7516 g_return_if_fail (GTK_IS_SHEET (sheet
));
7519 range
= sheet
->range
;
7523 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7524 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7525 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7527 attributes
.background
= *color
;
7529 attributes
.background
= sheet
->bg_color
;
7531 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7539 if(!GTK_SHEET_IS_FROZEN(sheet
))
7540 gtk_sheet_range_draw(sheet
, &range
);
7545 gtk_sheet_range_set_foreground(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7548 GtkSheetCellAttr attributes
;
7549 GtkSheetRange range
;
7551 g_return_if_fail (sheet
!= NULL
);
7552 g_return_if_fail (GTK_IS_SHEET (sheet
));
7555 range
= sheet
->range
;
7559 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7560 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7561 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7564 attributes
.foreground
= *color
;
7566 gdk_color_black(gdk_colormap_get_system(), &attributes
.foreground
);
7568 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7571 if(!GTK_SHEET_IS_FROZEN(sheet
))
7572 gtk_sheet_range_draw(sheet
, &range
);
7577 gtk_sheet_range_set_justification(GtkSheet
*sheet
, const GtkSheetRange
*urange
,
7578 GtkJustification just
)
7581 GtkSheetCellAttr attributes
;
7582 GtkSheetRange range
;
7584 g_return_if_fail (sheet
!= NULL
);
7585 g_return_if_fail (GTK_IS_SHEET (sheet
));
7588 range
= sheet
->range
;
7592 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7593 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7594 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7595 attributes
.justification
= just
;
7596 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7599 range
.col0
= sheet
->view
.col0
;
7600 range
.coli
= sheet
->view
.coli
;
7602 if(!GTK_SHEET_IS_FROZEN(sheet
))
7603 gtk_sheet_range_draw(sheet
, &range
);
7608 gtk_sheet_column_set_justification(GtkSheet
*sheet
, gint col
,
7609 GtkJustification justification
)
7611 g_return_if_fail (sheet
!= NULL
);
7612 g_return_if_fail (GTK_IS_SHEET (sheet
));
7614 if(col
> sheet
->maxcol
) return;
7616 sheet
->column
[col
].justification
= justification
;
7618 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
) &&
7619 col
>= MIN_VISIBLE_COLUMN(sheet
) && col
<= MAX_VISIBLE_COLUMN(sheet
))
7620 gtk_sheet_range_draw(sheet
, NULL
);
7625 gtk_sheet_range_set_editable(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gboolean editable
)
7628 GtkSheetCellAttr attributes
;
7629 GtkSheetRange range
;
7631 g_return_if_fail (sheet
!= NULL
);
7632 g_return_if_fail (GTK_IS_SHEET (sheet
));
7635 range
= sheet
->range
;
7639 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7640 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7641 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7642 attributes
.is_editable
= editable
;
7643 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7646 if(!GTK_SHEET_IS_FROZEN(sheet
))
7647 gtk_sheet_range_draw(sheet
, &range
);
7652 gtk_sheet_range_set_visible(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gboolean visible
)
7655 GtkSheetCellAttr attributes
;
7656 GtkSheetRange range
;
7658 g_return_if_fail (sheet
!= NULL
);
7659 g_return_if_fail (GTK_IS_SHEET (sheet
));
7662 range
= sheet
->range
;
7666 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7667 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7668 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7669 attributes
.is_visible
=visible
;
7670 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7673 if(!GTK_SHEET_IS_FROZEN(sheet
))
7674 gtk_sheet_range_draw(sheet
, &range
);
7679 gtk_sheet_range_set_border(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gint mask
,
7680 guint width
, gint line_style
)
7683 GtkSheetCellAttr attributes
;
7684 GtkSheetRange range
;
7686 g_return_if_fail (sheet
!= NULL
);
7687 g_return_if_fail (GTK_IS_SHEET (sheet
));
7690 range
= sheet
->range
;
7694 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7695 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7696 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7697 attributes
.border
.mask
= mask
;
7698 attributes
.border
.width
= width
;
7699 attributes
.border
.line_style
=line_style
;
7700 attributes
.border
.cap_style
=GDK_CAP_NOT_LAST
;
7701 attributes
.border
.join_style
=GDK_JOIN_MITER
;
7702 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7710 if(!GTK_SHEET_IS_FROZEN(sheet
))
7711 gtk_sheet_range_draw(sheet
, &range
);
7716 gtk_sheet_range_set_border_color(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7719 GtkSheetCellAttr attributes
;
7720 GtkSheetRange range
;
7722 g_return_if_fail (sheet
!= NULL
);
7723 g_return_if_fail (GTK_IS_SHEET (sheet
));
7726 range
= sheet
->range
;
7730 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7731 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7732 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7733 attributes
.border
.color
= *color
;
7734 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7737 if(!GTK_SHEET_IS_FROZEN(sheet
))
7738 gtk_sheet_range_draw(sheet
, &range
);
7743 gtk_sheet_range_set_font(GtkSheet
*sheet
, const GtkSheetRange
*urange
, PangoFontDescription
*font
)
7747 GtkSheetCellAttr attributes
;
7748 GtkSheetRange range
;
7749 PangoContext
*context
;
7750 PangoFontMetrics
*metrics
;
7752 g_return_if_fail (sheet
!= NULL
);
7753 g_return_if_fail (GTK_IS_SHEET (sheet
));
7756 range
= sheet
->range
;
7760 gtk_sheet_freeze(sheet
);
7762 context
= gtk_widget_get_pango_context(GTK_WIDGET(sheet
));
7763 metrics
= pango_context_get_metrics(context
,
7765 pango_context_get_language(context
));
7766 font_height
= pango_font_metrics_get_descent(metrics
) +
7767 pango_font_metrics_get_ascent(metrics
);
7768 font_height
= PANGO_PIXELS(font_height
) + 2*CELLOFFSET
;
7770 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7771 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7772 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7773 attributes
.font_desc
= font
;
7774 if(font_height
> sheet
->row
[i
].height
){
7775 sheet
->row
[i
].height
= font_height
;
7776 gtk_sheet_recalc_top_ypixels(sheet
, i
);
7779 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7782 gtk_sheet_thaw(sheet
);
7783 pango_font_metrics_unref(metrics
);
7787 gtk_sheet_set_cell_attributes(GtkSheet
*sheet
, gint row
, gint col
, GtkSheetCellAttr attributes
)
7789 GtkSheetCell
**cell
;
7791 if(row
> sheet
->maxrow
|| col
>sheet
->maxcol
) return;
7793 CheckBounds(sheet
, row
, col
);
7795 cell
= &sheet
->data
[row
][col
];
7798 (*cell
) = gtk_sheet_cell_new();
7803 if((*cell
)->attributes
== NULL
)
7804 (*cell
)->attributes
= g_new(GtkSheetCellAttr
, 1);
7806 *((*cell
)->attributes
) = attributes
;
7810 gtk_sheet_get_attributes(GtkSheet
*sheet
, gint row
, gint col
, GtkSheetCellAttr
*attributes
)
7812 GtkSheetCell
**cell
= NULL
;
7814 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
7815 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
7817 if(row
< 0 || col
< 0) return FALSE
;
7819 if(row
> sheet
->maxallocrow
|| col
> sheet
->maxalloccol
){
7820 init_attributes(sheet
, col
, attributes
);
7824 if(row
<= sheet
->maxallocrow
&& col
<= sheet
->maxalloccol
){
7825 if(sheet
->data
[row
] && sheet
->data
[row
][col
])
7826 cell
= &sheet
->data
[row
][col
];
7827 if(cell
== NULL
|| *cell
== NULL
){
7828 init_attributes(sheet
, col
, attributes
);
7831 if((*cell
)->attributes
== NULL
){
7832 init_attributes(sheet
, col
, attributes
);
7835 *attributes
= *(sheet
->data
[row
][col
]->attributes
);
7836 if(sheet
->column
[col
].justification
!= GTK_JUSTIFY_FILL
)
7837 attributes
->justification
= sheet
->column
[col
].justification
;
7845 init_attributes(GtkSheet
*sheet
, gint col
, GtkSheetCellAttr
*attributes
)
7847 /* DEFAULT VALUES */
7848 attributes
->foreground
= GTK_WIDGET(sheet
)->style
->black
;
7849 attributes
->background
= sheet
->bg_color
;
7850 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
7851 GdkColormap
*colormap
;
7852 colormap
=gdk_colormap_get_system();
7853 gdk_color_black(colormap
, &attributes
->foreground
);
7854 attributes
->background
= sheet
->bg_color
;
7856 attributes
->justification
= sheet
->column
[col
].justification
;
7857 attributes
->border
.width
= 0;
7858 attributes
->border
.line_style
= GDK_LINE_SOLID
;
7859 attributes
->border
.cap_style
= GDK_CAP_NOT_LAST
;
7860 attributes
->border
.join_style
= GDK_JOIN_MITER
;
7861 attributes
->border
.mask
= 0;
7862 attributes
->border
.color
= GTK_WIDGET(sheet
)->style
->black
;
7863 attributes
->is_editable
= TRUE
;
7864 attributes
->is_visible
= TRUE
;
7865 attributes
->font
= GTK_WIDGET(sheet
)->style
->private_font
;
7866 attributes
->font_desc
= GTK_WIDGET(sheet
)->style
->font_desc
;
7870 /**********************************************************************
7871 * Memory allocation routines:
7872 * AddRow & AddColumn allocate memory for GtkSheetColumn & GtkSheetRow structs.
7877 * GrowSheet allocates memory for the sheet cells contents using an array of
7878 * pointers. Alternative to this could be a linked list or a hash table.
7879 * CheckBounds checks whether the given cell is currently allocated or not.
7880 * If not, it calls to GrowSheet.
7881 **********************************************************************/
7884 AddColumn(GtkSheet
*tbl
, gint ncols
)
7888 if(ncols
== -1 && tbl
->maxcol
== 0)
7894 tbl
->maxcol
+= ncols
;
7895 tbl
->column
= (GtkSheetColumn
*)g_realloc(tbl
->column
,(tbl
->maxcol
+1)*
7896 sizeof(GtkSheetColumn
));
7899 for(i
=tbl
->maxcol
-ncols
+1; i
<= tbl
->maxcol
; i
++){
7900 tbl
->column
[i
].width
=DEFAULT_COLUMN_WIDTH
;
7901 tbl
->column
[i
].button
.label
=NULL
;
7902 tbl
->column
[i
].button
.child
=NULL
;
7903 tbl
->column
[i
].button
.state
=GTK_STATE_NORMAL
;
7904 tbl
->column
[i
].button
.justification
=GTK_JUSTIFY_CENTER
;
7905 tbl
->column
[i
].button
.label_visible
= TRUE
;
7906 tbl
->column
[i
].name
=NULL
;
7907 tbl
->column
[i
].is_visible
=TRUE
;
7908 tbl
->column
[i
].is_sensitive
=TRUE
;
7909 tbl
->column
[i
].left_text_column
=i
;
7910 tbl
->column
[i
].right_text_column
=i
;
7911 tbl
->column
[i
].justification
=GTK_JUSTIFY_FILL
;
7912 tbl
->column
[i
].requisition
=DEFAULT_COLUMN_WIDTH
;
7915 tbl
->column
[i
].left_text_column
=tbl
->column
[i
-1].left_text_column
;
7916 tbl
->column
[i
].left_xpixel
=tbl
->column
[i
-1].left_xpixel
+
7917 tbl
->column
[i
-1].width
;
7921 tbl
->column
[i
].left_xpixel
=tbl
->row_title_area
.width
;
7922 if(!tbl
->row_titles_visible
)
7923 tbl
->column
[i
].left_xpixel
=0;
7930 AddRow(GtkSheet
*tbl
, gint nrows
)
7934 if(nrows
== -1 && tbl
->maxrow
== 0)
7940 tbl
->maxrow
+= nrows
;
7941 tbl
->row
= (GtkSheetRow
*)g_realloc(tbl
->row
,(tbl
->maxrow
+1)*
7942 sizeof(GtkSheetRow
));
7945 for(i
=tbl
->maxrow
-nrows
+1; i
<= tbl
->maxrow
; i
++){
7946 tbl
->row
[i
].requisition
=tbl
->row
[i
].height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl
));
7947 tbl
->row
[i
].button
.label
=NULL
;
7948 tbl
->row
[i
].button
.child
=NULL
;
7949 tbl
->row
[i
].button
.state
=GTK_STATE_NORMAL
;
7950 tbl
->row
[i
].button
.justification
=GTK_JUSTIFY_CENTER
;
7951 tbl
->row
[i
].button
.label_visible
= TRUE
;
7952 tbl
->row
[i
].name
=NULL
;
7953 tbl
->row
[i
].is_visible
=TRUE
;
7954 tbl
->row
[i
].is_sensitive
=TRUE
;
7956 tbl
->row
[i
].top_ypixel
=tbl
->row
[i
-1].top_ypixel
+tbl
->row
[i
-1].height
;
7959 tbl
->row
[i
].top_ypixel
=tbl
->column_title_area
.height
;
7960 if(!tbl
->column_titles_visible
)
7961 tbl
->row
[i
].top_ypixel
=0;
7968 InsertRow(GtkSheet
*tbl
, gint row
, gint nrows
)
7972 GtkSheetCell
**auxdata
;
7977 for(i
=tbl
->maxrow
; i
>=row
+nrows
; i
--){
7978 auxrow
= tbl
->row
[i
];
7979 tbl
->row
[i
]=tbl
->row
[i
-nrows
];
7980 tbl
->row
[i
].is_visible
=tbl
->row
[i
-nrows
].is_visible
;
7981 tbl
->row
[i
].is_sensitive
=tbl
->row
[i
-nrows
].is_sensitive
;
7982 if(auxrow
.is_visible
)
7983 tbl
->row
[i
].top_ypixel
+=nrows
*DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl
));
7984 tbl
->row
[i
-nrows
]=auxrow
;
7987 if(row
<= tbl
->maxallocrow
){
7989 GrowSheet(tbl
,nrows
,0);
7991 for(i
=tbl
->maxallocrow
; i
>=row
+nrows
; i
--){
7992 auxdata
= tbl
->data
[i
];
7993 tbl
->data
[i
]=tbl
->data
[i
-nrows
];
7996 for(j
=0; j
<=tbl
->maxalloccol
; j
++,pp
++){
7997 if(*pp
!=(GtkSheetCell
*)NULL
)
8001 tbl
->data
[i
-nrows
]=auxdata
;
8004 gtk_sheet_recalc_top_ypixels(tbl
, 0);
8009 InsertColumn(GtkSheet
*tbl
, gint col
, gint ncols
)
8012 GtkSheetColumn auxcol
;
8014 AddColumn(tbl
,ncols
);
8016 for(i
=tbl
->maxcol
; i
>=col
+ncols
; i
--){
8017 auxcol
= tbl
->column
[i
];
8018 tbl
->column
[i
]=tbl
->column
[i
-ncols
];
8019 tbl
->column
[i
].is_visible
=tbl
->column
[i
-ncols
].is_visible
;
8020 tbl
->column
[i
].is_sensitive
=tbl
->column
[i
-ncols
].is_sensitive
;
8021 tbl
->column
[i
].left_text_column
=tbl
->column
[i
-ncols
].left_text_column
;
8022 tbl
->column
[i
].right_text_column
=tbl
->column
[i
-ncols
].right_text_column
;
8023 tbl
->column
[i
].justification
=tbl
->column
[i
-ncols
].justification
;
8024 if(auxcol
.is_visible
) tbl
->column
[i
].left_xpixel
+=ncols
*DEFAULT_COLUMN_WIDTH
;
8025 tbl
->column
[i
-ncols
]=auxcol
;
8028 if(col
<= tbl
->maxalloccol
){
8030 GrowSheet(tbl
,0,ncols
);
8032 for(i
=0; i
<=tbl
->maxallocrow
; i
++){
8033 for(j
=tbl
->maxalloccol
; j
>=col
+ncols
; j
--){
8034 gtk_sheet_real_cell_clear(tbl
, i
, j
, TRUE
);
8035 tbl
->data
[i
][j
]=tbl
->data
[i
][j
-ncols
];
8036 if(tbl
->data
[i
][j
]) tbl
->data
[i
][j
]->col
=j
;
8037 tbl
->data
[i
][j
-ncols
]=NULL
;
8041 gtk_sheet_recalc_left_xpixels(tbl
, 0);
8046 DeleteRow(GtkSheet
*tbl
, gint row
, gint nrows
)
8048 GtkSheetCell
**auxdata
= NULL
;
8051 if(nrows
<= 0 || row
> tbl
->maxrow
) return TRUE
;
8053 nrows
=MIN(nrows
,tbl
->maxrow
-row
+1);
8055 for(i
=row
; i
<row
+nrows
; i
++){
8056 if(tbl
->row
[i
].name
){
8057 g_free(tbl
->row
[i
].name
);
8058 tbl
->row
[i
].name
= NULL
;
8060 if(tbl
->row
[i
].button
.label
){
8061 g_free(tbl
->row
[i
].button
.label
);
8062 tbl
->row
[i
].button
.label
= NULL
;
8066 for(i
=row
; i
<=tbl
->maxrow
-nrows
; i
++){
8067 if(i
+nrows
<= tbl
->maxrow
){
8068 tbl
->row
[i
]=tbl
->row
[i
+nrows
];
8072 if(row
<= tbl
->maxallocrow
){
8074 for(i
=row
; i
<=tbl
->maxrow
-nrows
; i
++){
8075 if(i
<=tbl
->maxallocrow
){
8076 auxdata
=tbl
->data
[i
];
8077 for(j
=0; j
<=tbl
->maxalloccol
; j
++){
8078 gtk_sheet_real_cell_clear(tbl
, i
, j
, TRUE
);
8081 if(i
+nrows
<=tbl
->maxallocrow
){
8082 tbl
->data
[i
]=tbl
->data
[i
+nrows
];
8083 tbl
->data
[i
+nrows
]=auxdata
;
8084 for(j
=0; j
<=tbl
->maxalloccol
; j
++){
8085 if(tbl
->data
[i
][j
]) tbl
->data
[i
][j
]->row
=i
;
8090 for(i
=tbl
->maxrow
-nrows
+1; i
<=tbl
->maxallocrow
; i
++){
8091 if(i
> 0 && tbl
->data
[i
]){
8092 g_free(tbl
->data
[i
]);
8093 tbl
->data
[i
] = NULL
;
8097 tbl
->maxallocrow
-=MIN(nrows
,tbl
->maxallocrow
-row
+1);
8098 tbl
->maxallocrow
= MIN(tbl
->maxallocrow
, tbl
->maxrow
);
8103 gtk_sheet_recalc_top_ypixels(tbl
, 0);
8108 DeleteColumn(GtkSheet
*tbl
, gint column
, gint ncols
)
8111 GtkSheetColumn auxcol
;
8113 ncols
= MIN(ncols
,tbl
->maxcol
-column
+1);
8115 if(ncols
<= 0 || column
> tbl
->maxcol
) return TRUE
;
8117 for(i
=column
; i
<column
+ncols
; i
++){
8118 auxcol
=tbl
->column
[i
];
8119 if(tbl
->column
[i
].name
){
8120 g_free(tbl
->column
[i
].name
);
8121 tbl
->column
[i
].name
= NULL
;
8123 if(tbl
->column
[i
].button
.label
){
8124 g_free(tbl
->column
[i
].button
.label
);
8125 tbl
->column
[i
].button
.label
= NULL
;
8129 for(i
=column
; i
<=tbl
->maxcol
-ncols
; i
++){
8130 if(i
+ncols
<= tbl
->maxcol
){
8131 tbl
->column
[i
]=tbl
->column
[i
+ncols
];
8135 if(column
<= tbl
->maxalloccol
){
8137 for(i
=column
; i
<=tbl
->maxcol
-ncols
; i
++){
8138 if(i
<=tbl
->maxalloccol
){
8139 for(j
=0; j
<=tbl
->maxallocrow
; j
++){
8140 gtk_sheet_real_cell_clear(tbl
, j
, i
, TRUE
);
8141 if(i
+ncols
<= tbl
->maxalloccol
){
8142 tbl
->data
[j
][i
] = tbl
->data
[j
][i
+ncols
];
8143 tbl
->data
[j
][i
+ncols
] = NULL
;
8144 if(tbl
->data
[j
][i
]) tbl
->data
[j
][i
]->col
=i
;
8151 tbl
->maxalloccol
-=MIN(ncols
,tbl
->maxalloccol
-column
+1);
8152 tbl
->maxalloccol
= MIN(tbl
->maxalloccol
, tbl
->maxcol
);
8155 gtk_sheet_recalc_left_xpixels(tbl
, 0);
8160 GrowSheet(GtkSheet
*tbl
, gint newrows
, gint newcols
)
8163 gint inirow
, inicol
;
8165 inirow
= tbl
->maxallocrow
+ 1;
8166 inicol
= tbl
->maxalloccol
+ 1;
8168 tbl
->maxalloccol
= tbl
->maxalloccol
+ newcols
;
8169 tbl
->maxallocrow
= tbl
->maxallocrow
+ newrows
;
8172 tbl
->data
= (GtkSheetCell
***)
8173 g_realloc(tbl
->data
,(tbl
->maxallocrow
+1)*sizeof(GtkSheetCell
**)+sizeof(double));
8175 for(i
=inirow
; i
<= tbl
->maxallocrow
; i
++){
8176 tbl
->data
[i
] = (GtkSheetCell
**) \
8177 g_malloc((tbl
->maxcol
+1)*sizeof(GtkSheetCell
*)+sizeof(double));
8178 for(j
=0; j
<inicol
; j
++) {
8179 tbl
->data
[i
][j
] = NULL
;
8186 for(i
=0; i
<= tbl
->maxallocrow
; i
++) {
8187 tbl
->data
[i
] = (GtkSheetCell
**) \
8188 g_realloc(tbl
->data
[i
],(tbl
->maxalloccol
+1)*sizeof(GtkSheetCell
*)+sizeof(double));
8189 for(j
=inicol
; j
<= tbl
->maxalloccol
; j
++) {
8190 tbl
->data
[i
][j
] = NULL
;
8199 CheckBounds(GtkSheet
*tbl
, gint row
, gint col
)
8201 gint newrows
=0,newcols
=0;
8203 if(col
>tbl
->maxalloccol
) newcols
=col
-tbl
->maxalloccol
;
8204 if(row
>tbl
->maxallocrow
) newrows
=row
-tbl
->maxallocrow
;
8205 if(newrows
>0 || newcols
>0) GrowSheet(tbl
, newrows
, newcols
);
8209 /********************************************************************
8210 * Container Functions:
8215 * gtk_sheet_move_child
8216 * gtk_sheet_position_child
8217 * gtk_sheet_position_children
8218 * gtk_sheet_realize_child
8219 * gtk_sheet_get_child_at
8220 ********************************************************************/
8223 gtk_sheet_put(GtkSheet
*sheet
, GtkWidget
*child
, gint x
, gint y
)
8225 GtkRequisition child_requisition
;
8226 GtkSheetChild
*child_info
;
8228 g_return_val_if_fail(sheet
!= NULL
, NULL
);
8229 g_return_val_if_fail(GTK_IS_SHEET(sheet
), NULL
);
8230 g_return_val_if_fail(child
!= NULL
, NULL
);
8231 g_return_val_if_fail(child
->parent
== NULL
, NULL
);
8233 child_info
= g_new (GtkSheetChild
, 1);
8234 child_info
->widget
= child
;
8237 child_info
->attached_to_cell
= FALSE
;
8238 child_info
->floating
= TRUE
;
8239 child_info
->xpadding
= child_info
->ypadding
= 0;
8240 child_info
->xexpand
= child_info
->yexpand
= FALSE
;
8241 child_info
->xshrink
= child_info
->yshrink
= FALSE
;
8242 child_info
->xfill
= child_info
->yfill
= FALSE
;
8244 sheet
->children
= g_list_append(sheet
->children
, child_info
);
8246 gtk_widget_set_parent (child
, GTK_WIDGET(sheet
));
8248 gtk_widget_size_request(child
, &child_requisition
);
8250 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8252 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8253 (!GTK_WIDGET_REALIZED(child
) || GTK_WIDGET_NO_WINDOW(child
)))
8254 gtk_sheet_realize_child(sheet
, child_info
);
8256 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8257 !GTK_WIDGET_MAPPED(child
))
8258 gtk_widget_map(child
);
8261 gtk_sheet_position_child(sheet
, child_info
);
8263 /* This will avoid drawing on the titles */
8265 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)))
8267 if(sheet
->row_titles_visible
)
8268 gdk_window_show(sheet
->row_title_window
);
8269 if(sheet
->column_titles_visible
)
8270 gdk_window_show(sheet
->column_title_window
);
8273 return (child_info
);
8277 gtk_sheet_attach_floating (GtkSheet
*sheet
,
8282 GtkSheetChild
*child
;
8284 if(row
< 0 || col
< 0){
8285 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8289 gtk_sheet_get_cell_area(sheet
, row
, col
, &area
);
8290 child
= gtk_sheet_put(sheet
, widget
, area
.x
, area
.y
);
8291 child
->attached_to_cell
= TRUE
;
8297 gtk_sheet_attach_default (GtkSheet
*sheet
,
8301 if(row
< 0 || col
< 0){
8302 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8306 gtk_sheet_attach(sheet
, widget
, row
, col
, GTK_EXPAND
|GTK_FILL
, GTK_EXPAND
|GTK_FILL
, 0, 0);
8310 gtk_sheet_attach (GtkSheet
*sheet
,
8319 GtkSheetChild
*child
= NULL
;
8321 if(row
< 0 || col
< 0){
8322 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8326 child
= g_new0(GtkSheetChild
, 1);
8327 child
->attached_to_cell
= TRUE
;
8328 child
->floating
= FALSE
;
8329 child
->widget
= widget
;
8332 child
->xpadding
= xpadding
;
8333 child
->ypadding
= ypadding
;
8334 child
->xexpand
= (xoptions
& GTK_EXPAND
) != 0;
8335 child
->yexpand
= (yoptions
& GTK_EXPAND
) != 0;
8336 child
->xshrink
= (xoptions
& GTK_SHRINK
) != 0;
8337 child
->yshrink
= (yoptions
& GTK_SHRINK
) != 0;
8338 child
->xfill
= (xoptions
& GTK_FILL
) != 0;
8339 child
->yfill
= (yoptions
& GTK_FILL
) != 0;
8341 sheet
->children
= g_list_append(sheet
->children
, child
);
8343 gtk_sheet_get_cell_area(sheet
, row
, col
, &area
);
8345 child
->x
= area
.x
+ child
->xpadding
;
8346 child
->y
= area
.y
+ child
->ypadding
;
8348 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8350 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8351 (!GTK_WIDGET_REALIZED(widget
) || GTK_WIDGET_NO_WINDOW(widget
)))
8352 gtk_sheet_realize_child(sheet
, child
);
8354 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8355 !GTK_WIDGET_MAPPED(widget
))
8356 gtk_widget_map(widget
);
8359 gtk_sheet_position_child(sheet
, child
);
8361 /* This will avoid drawing on the titles */
8363 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)))
8365 if(GTK_SHEET_ROW_TITLES_VISIBLE(sheet
))
8366 gdk_window_show(sheet
->row_title_window
);
8367 if(GTK_SHEET_COL_TITLES_VISIBLE(sheet
))
8368 gdk_window_show(sheet
->column_title_window
);
8374 gtk_sheet_button_attach (GtkSheet
*sheet
,
8378 GtkSheetButton
*button
;
8379 GtkSheetChild
*child
;
8380 GtkRequisition button_requisition
;
8382 if(row
>= 0 && col
>= 0) return;
8383 if(row
< 0 && col
< 0) return;
8385 child
= g_new (GtkSheetChild
, 1);
8386 child
->widget
= widget
;
8389 child
->attached_to_cell
= TRUE
;
8390 child
->floating
= FALSE
;
8393 child
->xpadding
= child
->ypadding
= 0;
8394 child
->xshrink
= child
->yshrink
= FALSE
;
8395 child
->xfill
= child
->yfill
= FALSE
;
8398 button
= &sheet
->column
[col
].button
;
8399 button
->child
= child
;
8403 button
= &sheet
->row
[row
].button
;
8404 button
->child
= child
;
8407 sheet
->children
= g_list_append(sheet
->children
, child
);
8409 gtk_sheet_button_size_request(sheet
, button
, &button_requisition
);
8412 if(button_requisition
.height
> sheet
->column_title_area
.height
)
8413 sheet
->column_title_area
.height
= button_requisition
.height
;
8414 if(button_requisition
.width
> sheet
->column
[col
].width
)
8415 sheet
->column
[col
].width
= button_requisition
.width
;
8419 if(button_requisition
.width
> sheet
->row_title_area
.width
)
8420 sheet
->row_title_area
.width
= button_requisition
.width
;
8421 if(button_requisition
.height
> sheet
->row
[row
].height
)
8422 sheet
->row
[row
].height
= button_requisition
.height
;
8425 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8427 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8428 (!GTK_WIDGET_REALIZED(widget
) || GTK_WIDGET_NO_WINDOW(widget
)))
8429 gtk_sheet_realize_child(sheet
, child
);
8431 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8432 !GTK_WIDGET_MAPPED(widget
))
8433 gtk_widget_map(widget
);
8436 if(row
== -1) size_allocate_column_title_buttons(sheet
);
8437 if(col
== -1) size_allocate_row_title_buttons(sheet
);
8442 label_size_request(GtkSheet
*sheet
, gchar
*label
, GtkRequisition
*req
)
8447 gint row_height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
)) - 2*CELLOFFSET
+ 2;
8453 while(words
&& *words
!= '\0'){
8454 if(*words
== '\n' || *(words
+1) == '\0'){
8455 req
->height
+= row_height
;
8458 req
->width
= MAX(req
->width
, STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, word
));
8466 if(n
> 0) req
->height
-= 2;
8470 gtk_sheet_button_size_request (GtkSheet
*sheet
,
8471 GtkSheetButton
*button
,
8472 GtkRequisition
*button_requisition
)
8474 GtkRequisition requisition
;
8475 GtkRequisition label_requisition
;
8477 if(gtk_sheet_autoresize(sheet
) && button
->label
&& strlen(button
->label
) > 0){
8478 label_size_request(sheet
, button
->label
, &label_requisition
);
8479 label_requisition
.width
+= 2*CELLOFFSET
;
8480 label_requisition
.height
+= 2*CELLOFFSET
;
8482 label_requisition
.height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
8483 label_requisition
.width
= COLUMN_MIN_WIDTH
;
8488 gtk_widget_size_request(button
->child
->widget
, &requisition
);
8489 requisition
.width
+= 2*button
->child
->xpadding
;
8490 requisition
.height
+= 2*button
->child
->ypadding
;
8491 requisition
.width
+= 2*sheet
->button
->style
->xthickness
;
8492 requisition
.height
+= 2*sheet
->button
->style
->ythickness
;
8496 requisition
.height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
8497 requisition
.width
= COLUMN_MIN_WIDTH
;
8500 *button_requisition
= requisition
;
8501 button_requisition
->width
= MAX(requisition
.width
, label_requisition
.width
);
8502 button_requisition
->height
= MAX(requisition
.height
, label_requisition
.height
);
8507 gtk_sheet_row_size_request (GtkSheet
*sheet
,
8511 GtkRequisition button_requisition
;
8514 gtk_sheet_button_size_request(sheet
, &sheet
->row
[row
].button
, &button_requisition
);
8516 *requisition
= button_requisition
.height
;
8518 children
= sheet
->children
;
8520 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
8521 GtkRequisition child_requisition
;
8523 if(child
->attached_to_cell
&& child
->row
== row
&& child
->col
!= -1 && !child
->floating
&& !child
->yshrink
){
8524 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8526 if(child_requisition
.height
+ 2 * child
->ypadding
> *requisition
)
8527 *requisition
= child_requisition
.height
+ 2 * child
->ypadding
;
8529 children
= g_list_next(children
);
8532 sheet
->row
[row
].requisition
= *requisition
;
8536 gtk_sheet_column_size_request (GtkSheet
*sheet
,
8540 GtkRequisition button_requisition
;
8543 gtk_sheet_button_size_request(sheet
, &sheet
->column
[col
].button
, &button_requisition
);
8545 *requisition
= button_requisition
.width
;
8547 children
= sheet
->children
;
8549 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
8550 GtkRequisition child_requisition
;
8552 if(child
->attached_to_cell
&& child
->col
== col
&& child
->row
!= -1 && !child
->floating
&& !child
->xshrink
){
8553 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8555 if(child_requisition
.width
+ 2 * child
->xpadding
> *requisition
)
8556 *requisition
= child_requisition
.width
+ 2 * child
->xpadding
;
8558 children
= g_list_next(children
);
8561 sheet
->column
[col
].requisition
= *requisition
;
8565 gtk_sheet_move_child(GtkSheet
*sheet
, GtkWidget
*widget
, gint x
, gint y
)
8567 GtkSheetChild
*child
;
8570 g_return_if_fail(sheet
!= NULL
);
8571 g_return_if_fail(GTK_IS_SHEET(sheet
));
8573 children
= sheet
->children
;
8576 child
= children
->data
;
8578 if(child
->widget
== widget
){
8581 child
->row
= ROW_FROM_YPIXEL(sheet
, y
);
8582 child
->col
= COLUMN_FROM_XPIXEL(sheet
, x
);
8583 gtk_sheet_position_child(sheet
, child
);
8587 children
= g_list_next(children
);
8590 g_warning("Widget must be a GtkSheet child");
8595 gtk_sheet_position_child(GtkSheet
*sheet
, GtkSheetChild
*child
)
8597 GtkRequisition child_requisition
;
8598 GtkAllocation child_allocation
;
8604 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8606 if(sheet
->column_titles_visible
)
8607 yoffset
= sheet
->column_title_area
.height
;
8609 if(sheet
->row_titles_visible
)
8610 xoffset
= sheet
->row_title_area
.width
;
8612 if(child
->attached_to_cell
){
8614 child->x = COLUMN_LEFT_XPIXEL(sheet, child->col);
8615 child->y = ROW_TOP_YPIXEL(sheet, child->row);
8617 if(sheet->row_titles_visible)
8618 child->x-=sheet->row_title_area.width;
8619 if(sheet->column_titles_visible)
8620 child->y-=sheet->column_title_area.height;
8622 width = sheet->column[child->col].width;
8623 height = sheet->row[child->row].height;
8626 gtk_sheet_get_cell_area(sheet
, child
->row
, child
->col
, &area
);
8627 child
->x
= area
.x
+ child
->xpadding
;
8628 child
->y
= area
.y
+ child
->ypadding
;
8630 if(!child
->floating
){
8631 if(child_requisition
.width
+ 2*child
->xpadding
<= sheet
->column
[child
->col
].width
){
8633 child_requisition
.width
= child_allocation
.width
= sheet
->column
[child
->col
].width
- 2*child
->xpadding
;
8636 child
->x
= area
.x
+ sheet
->column
[child
->col
].width
/ 2 -
8637 child_requisition
.width
/ 2;
8639 child_allocation
.width
= child_requisition
.width
;
8642 if(!child
->xshrink
){
8643 gtk_sheet_set_column_width(sheet
, child
->col
, child_requisition
.width
+ 2 * child
->xpadding
);
8645 child_allocation
.width
= sheet
->column
[child
->col
].width
- 2*child
->xpadding
;
8648 if(child_requisition
.height
+ 2*child
->ypadding
<= sheet
->row
[child
->row
].height
){
8650 child_requisition
.height
= child_allocation
.height
= sheet
->row
[child
->row
].height
- 2*child
->ypadding
;
8653 child
->y
= area
.y
+ sheet
->row
[child
->row
].height
/ 2 -
8654 child_requisition
.height
/ 2;
8656 child_allocation
.height
= child_requisition
.height
;
8659 if(!child
->yshrink
){
8660 gtk_sheet_set_row_height(sheet
, child
->row
, child_requisition
.height
+ 2 * child
->ypadding
);
8662 child_allocation
.height
= sheet
->row
[child
->row
].height
- 2*child
->ypadding
;
8665 child_allocation
.width
= child_requisition
.width
;
8666 child_allocation
.height
= child_requisition
.height
;
8669 x
= child_allocation
.x
= child
->x
+ xoffset
;
8670 y
= child_allocation
.y
= child
->y
+ yoffset
;
8674 x
= child_allocation
.x
= child
->x
+ sheet
->hoffset
+ xoffset
;
8675 x
= child_allocation
.x
= child
->x
+ xoffset
;
8676 y
= child_allocation
.y
= child
->y
+ sheet
->voffset
+ yoffset
;
8677 y
= child_allocation
.y
= child
->y
+ yoffset
;
8678 child_allocation
.width
= child_requisition
.width
;
8679 child_allocation
.height
= child_requisition
.height
;
8682 gtk_widget_size_allocate(child
->widget
, &child_allocation
);
8683 gtk_widget_queue_draw(child
->widget
);
8687 gtk_sheet_forall (GtkContainer
*container
,
8688 gboolean include_internals
,
8689 GtkCallback callback
,
8690 gpointer callback_data
)
8693 GtkSheetChild
*child
;
8696 g_return_if_fail (GTK_IS_SHEET (container
));
8697 g_return_if_fail (callback
!= NULL
);
8699 sheet
= GTK_SHEET (container
);
8701 children
= sheet
->children
;
8704 child
= children
->data
;
8705 children
= g_list_next(children
);
8707 (* callback
) (child
->widget
, callback_data
);
8710 (* callback
) (sheet
->button
, callback_data
);
8711 if(sheet
->sheet_entry
)
8712 (* callback
) (sheet
->sheet_entry
, callback_data
);
8717 gtk_sheet_position_children(GtkSheet
*sheet
)
8720 GtkSheetChild
*child
;
8722 children
= sheet
->children
;
8726 child
= (GtkSheetChild
*)children
->data
;
8728 if(child
->col
!=-1 && child
->row
!= -1)
8729 gtk_sheet_position_child(sheet
, child
);
8731 if(child
->row
== -1){
8732 if(child
->col
< MIN_VISIBLE_COLUMN(sheet
) ||
8733 child
->col
> MAX_VISIBLE_COLUMN(sheet
))
8734 gtk_sheet_child_hide(child
);
8736 gtk_sheet_child_show(child
);
8738 if(child
->col
== -1){
8739 if(child
->row
< MIN_VISIBLE_ROW(sheet
) ||
8740 child
->row
> MAX_VISIBLE_ROW(sheet
))
8741 gtk_sheet_child_hide(child
);
8743 gtk_sheet_child_show(child
);
8746 children
= g_list_next(children
);
8752 gtk_sheet_remove (GtkContainer
*container
, GtkWidget
*widget
)
8756 GtkSheetChild
*child
= 0;
8758 g_return_if_fail(container
!= NULL
);
8759 g_return_if_fail(GTK_IS_SHEET(container
));
8761 sheet
= GTK_SHEET(container
);
8763 children
= sheet
->children
;
8767 child
= (GtkSheetChild
*)children
->data
;
8769 if(child
->widget
== widget
) break;
8771 children
= g_list_next(children
);
8776 if(child
->row
== -1)
8777 sheet
->row
[child
->col
].button
.child
= NULL
;
8779 if(child
->col
== -1)
8780 sheet
->column
[child
->row
].button
.child
= NULL
;
8782 gtk_widget_unparent (widget
);
8783 child
->widget
= NULL
;
8785 sheet
->children
= g_list_remove_link (sheet
->children
, children
);
8786 g_list_free_1 (children
);
8793 gtk_sheet_realize_child(GtkSheet
*sheet
, GtkSheetChild
*child
)
8797 widget
= GTK_WIDGET(sheet
);
8799 if(GTK_WIDGET_REALIZED(widget
)){
8800 if(child
->row
== -1)
8801 gtk_widget_set_parent_window(child
->widget
, sheet
->column_title_window
);
8802 else if(child
->col
== -1)
8803 gtk_widget_set_parent_window(child
->widget
, sheet
->row_title_window
);
8805 gtk_widget_set_parent_window(child
->widget
, sheet
->sheet_window
);
8808 gtk_widget_set_parent(child
->widget
, widget
);
8814 gtk_sheet_get_child_at(GtkSheet
*sheet
, gint row
, gint col
)
8817 GtkSheetChild
*child
= 0;
8819 g_return_val_if_fail(sheet
!= NULL
, NULL
);
8820 g_return_val_if_fail(GTK_IS_SHEET(sheet
), NULL
);
8822 children
= sheet
->children
;
8826 child
= (GtkSheetChild
*)children
->data
;
8828 if(child
->attached_to_cell
)
8829 if(child
->row
== row
&& child
->col
== col
) break;
8831 children
= g_list_next(children
);
8834 if(children
) return child
;
8840 gtk_sheet_child_hide(GtkSheetChild
*child
)
8842 g_return_if_fail(child
!= NULL
);
8843 gtk_widget_hide(child
->widget
);
8847 gtk_sheet_child_show(GtkSheetChild
*child
)
8849 g_return_if_fail(child
!= NULL
);
8851 gtk_widget_show(child
->widget
);