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., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 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 "gtksheet_2_2.h"
48 #include "gtkextra-marshal.h"
50 /*------------------------------------------------------------------
51 * Gattrib specific includes -- stuff dealing with gattrib data structs.
52 * Included here in order to grab sheet_head->CHANGED, which is set
53 * when the user puts a new value in a cell.
54 *------------------------------------------------------------------*/
55 #include <libgeda/libgeda.h> /* geda library fcns */
56 #include "../include/struct.h" /* typdef and struct declarations */
57 #include "../include/prototype.h" /* function prototypes */
58 #include "../include/globals.h"
60 #ifdef HAVE_LIBDMALLOC
68 GTK_SHEET_IS_LOCKED
= 1 << 0,
69 GTK_SHEET_IS_FROZEN
= 1 << 1,
70 GTK_SHEET_IN_XDRAG
= 1 << 2,
71 GTK_SHEET_IN_YDRAG
= 1 << 3,
72 GTK_SHEET_IN_DRAG
= 1 << 4,
73 GTK_SHEET_IN_SELECTION
= 1 << 5,
74 GTK_SHEET_IN_RESIZE
= 1 << 6,
75 GTK_SHEET_IN_CLIP
= 1 << 7,
76 GTK_SHEET_REDRAW_PENDING
= 1 << 8,
79 #define GTK_SHEET_FLAGS(sheet) (GTK_SHEET (sheet)->flags)
80 #define GTK_SHEET_SET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) |= (flag))
81 #define GTK_SHEET_UNSET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) &= ~(flag))
83 #define GTK_SHEET_IS_FROZEN(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN)
84 #define GTK_SHEET_IN_XDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG)
85 #define GTK_SHEET_IN_YDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG)
86 #define GTK_SHEET_IN_DRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_DRAG)
87 #define GTK_SHEET_IN_SELECTION(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_SELECTION)
88 #define GTK_SHEET_IN_RESIZE(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_RESIZE)
89 #define GTK_SHEET_IN_CLIP(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_CLIP)
90 #define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING)
92 #define CELL_SPACING 1
94 #define TIMEOUT_SCROLL 20
95 #define TIMEOUT_FLASH 200
96 #define TIME_INTERVAL 8
97 #define COLUMN_MIN_WIDTH 10
102 #define DEFAULT_COLUMN_WIDTH 80
104 static inline guint
DEFAULT_ROW_HEIGHT(GtkWidget
*widget
)
106 if(!widget
->style
->font_desc
) return 24;
108 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
109 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
110 widget
->style
->font_desc
,
111 pango_context_get_language(context
));
112 guint val
= pango_font_metrics_get_descent(metrics
) +
113 pango_font_metrics_get_ascent(metrics
);
114 pango_font_metrics_unref(metrics
);
115 return PANGO_PIXELS(val
)+2*CELLOFFSET
;
118 static inline guint
DEFAULT_FONT_ASCENT(GtkWidget
*widget
)
120 if(!widget
->style
->font_desc
) return 12;
122 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
123 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
124 widget
->style
->font_desc
,
125 pango_context_get_language(context
));
126 guint val
= pango_font_metrics_get_ascent(metrics
);
127 pango_font_metrics_unref(metrics
);
128 return PANGO_PIXELS(val
);
131 static inline guint
STRING_WIDTH(GtkWidget
*widget
,
132 PangoFontDescription
*font
, const gchar
*text
)
137 layout
= gtk_widget_create_pango_layout (widget
, text
);
138 pango_layout_set_font_description (layout
, font
);
140 pango_layout_get_extents (layout
, NULL
, &rect
);
142 g_object_unref(G_OBJECT(layout
));
143 return PANGO_PIXELS(rect
.width
);
146 static inline guint
DEFAULT_FONT_DESCENT(GtkWidget
*widget
)
148 if(!widget
->style
->font_desc
) return 12;
150 PangoContext
*context
= gtk_widget_get_pango_context(widget
);
151 PangoFontMetrics
*metrics
= pango_context_get_metrics(context
,
152 widget
->style
->font_desc
,
153 pango_context_get_language(context
));
154 guint val
= pango_font_metrics_get_descent(metrics
);
155 pango_font_metrics_unref(metrics
);
156 return PANGO_PIXELS(val
);
160 /*! \brief gives the top pixel of the given row in context of
161 * the sheet's voffset
165 ROW_TOP_YPIXEL(GtkSheet
*sheet
, gint nrow
)
167 return (sheet
->voffset
+ sheet
->row
[nrow
].top_ypixel
);
171 /*! \brief returns the row index from a y pixel location in the
172 * context of the sheet's voffset
176 ROW_FROM_YPIXEL(GtkSheet
*sheet
, gint y
)
181 if(sheet
->column_titles_visible
) cy
+= sheet
->column_title_area
.height
;
183 for (i
= 0; i
<= sheet
->maxrow
; i
++)
185 if (y
>= cy
&& y
<= (cy
+ sheet
->row
[i
].height
) && sheet
->row
[i
].is_visible
)
187 if(sheet
->row
[i
].is_visible
) cy
+= sheet
->row
[i
].height
;
192 return sheet
->maxrow
;
196 /*! \brief gives the left pixel of the given column in context of
197 * the sheet's hoffset
201 COLUMN_LEFT_XPIXEL(GtkSheet
*sheet
, gint ncol
)
203 return (sheet
->hoffset
+ sheet
->column
[ncol
].left_xpixel
);
206 /*! \brief returns the column index from a x pixel location in the
207 * context of the sheet's hoffset
211 COLUMN_FROM_XPIXEL (GtkSheet
* sheet
,
217 if(sheet
->row_titles_visible
) cx
+= sheet
->row_title_area
.width
;
219 for (i
= 0; i
<= sheet
->maxcol
; i
++)
221 if (x
>= cx
&& x
<= (cx
+ sheet
->column
[i
].width
) && sheet
->column
[i
].is_visible
)
223 if(sheet
->column
[i
].is_visible
) cx
+= sheet
->column
[i
].width
;
228 return sheet
->maxcol
;
231 /*! \brief returns the total height of the sheet
234 static inline gint
SHEET_HEIGHT(GtkSheet
*sheet
)
239 if(sheet
->column_titles_visible
) cx
+= sheet
->column_title_area
.height
;
240 for (i
=0;i
<=sheet
->maxrow
; i
++)
241 if(sheet
->row
[i
].is_visible
) cx
+= sheet
->row
[i
].height
;
247 /*! \brief returns the total width of the sheet
250 static inline gint
SHEET_WIDTH(GtkSheet
*sheet
)
255 if(sheet
->row_titles_visible
) cx
+= sheet
->row_title_area
.width
;
256 for (i
=0;i
<=sheet
->maxcol
; i
++)
257 if(sheet
->column
[i
].is_visible
) cx
+= sheet
->column
[i
].width
;
262 #define MIN_VISIBLE_ROW(sheet) sheet->view.row0
263 #define MAX_VISIBLE_ROW(sheet) sheet->view.rowi
264 #define MIN_VISIBLE_COLUMN(sheet) sheet->view.col0
265 #define MAX_VISIBLE_COLUMN(sheet) sheet->view.coli
269 POSSIBLE_XDRAG(GtkSheet
*sheet
, gint x
, gint
*drag_column
)
273 column
=COLUMN_FROM_XPIXEL(sheet
, x
);
276 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,column
)+CELL_SPACING
;
277 if(x
<= xdrag
+DRAG_WIDTH
/2 && column
!= 0){
278 while(!sheet
->column
[column
-1].is_visible
&& column
>0) column
--;
279 *drag_column
=column
-1;
280 return sheet
->column
[column
-1].is_sensitive
;
283 xdrag
+=sheet
->column
[column
].width
;
284 if(x
>= xdrag
-DRAG_WIDTH
/2 && x
<= xdrag
+DRAG_WIDTH
/2)
285 return sheet
->column
[column
].is_sensitive
;
291 POSSIBLE_YDRAG(GtkSheet
*sheet
, gint y
, gint
*drag_row
)
295 row
=ROW_FROM_YPIXEL(sheet
, y
);
298 ydrag
=ROW_TOP_YPIXEL(sheet
,row
)+CELL_SPACING
;
299 if(y
<= ydrag
+DRAG_WIDTH
/2 && row
!= 0){
300 while(!sheet
->row
[row
-1].is_visible
&& row
>0) row
--;
302 return sheet
->row
[row
-1].is_sensitive
;
305 ydrag
+=sheet
->row
[row
].height
;
307 if(y
>= ydrag
-DRAG_WIDTH
/2 && y
<= ydrag
+DRAG_WIDTH
/2)
308 return sheet
->row
[row
].is_sensitive
;
314 static inline gint
POSSIBLE_DRAG(GtkSheet
*sheet
, gint x
, gint y
,
315 gint
*drag_row
, gint
*drag_column
)
319 *drag_column
=COLUMN_FROM_XPIXEL(sheet
,x
);
320 *drag_row
=ROW_FROM_YPIXEL(sheet
,y
);
322 if(x
>=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.col0
)-DRAG_WIDTH
/2 &&
323 x
<=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
324 sheet
->column
[sheet
->range
.coli
].width
+DRAG_WIDTH
/2){
325 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.row0
);
326 if(y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2){
327 *drag_row
=sheet
->range
.row0
;
330 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
331 sheet
->row
[sheet
->range
.rowi
].height
;
332 if(y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2){
333 *drag_row
=sheet
->range
.rowi
;
338 if(y
>=ROW_TOP_YPIXEL(sheet
,sheet
->range
.row0
)-DRAG_WIDTH
/2 &&
339 y
<=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
340 sheet
->row
[sheet
->range
.rowi
].height
+DRAG_WIDTH
/2){
341 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.col0
);
342 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2){
343 *drag_column
=sheet
->range
.col0
;
346 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
347 sheet
->column
[sheet
->range
.coli
].width
;
348 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2){
349 *drag_column
=sheet
->range
.coli
;
356 static inline gint
POSSIBLE_RESIZE(GtkSheet
*sheet
, gint x
, gint y
,
357 gint
*drag_row
, gint
*drag_column
)
361 xdrag
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->range
.coli
)+
362 sheet
->column
[sheet
->range
.coli
].width
;
364 ydrag
=ROW_TOP_YPIXEL(sheet
,sheet
->range
.rowi
)+
365 sheet
->row
[sheet
->range
.rowi
].height
;
367 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
368 ydrag
= ROW_TOP_YPIXEL(sheet
, sheet
->view
.row0
);
370 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
371 xdrag
= COLUMN_LEFT_XPIXEL(sheet
, sheet
->view
.col0
);
373 *drag_column
=COLUMN_FROM_XPIXEL(sheet
,x
);
374 *drag_row
=ROW_FROM_YPIXEL(sheet
,y
);
376 if(x
>=xdrag
-DRAG_WIDTH
/2 && x
<=xdrag
+DRAG_WIDTH
/2 &&
377 y
>=ydrag
-DRAG_WIDTH
/2 && y
<=ydrag
+DRAG_WIDTH
/2) return TRUE
;
382 static void gtk_sheet_class_init (GtkSheetClass
* klass
);
383 static void gtk_sheet_init (GtkSheet
* sheet
);
384 static void gtk_sheet_destroy (GtkObject
* object
);
385 static void gtk_sheet_finalize (GObject
* object
);
386 static void gtk_sheet_style_set (GtkWidget
*widget
,
387 GtkStyle
*previous_style
);
388 static void gtk_sheet_realize (GtkWidget
* widget
);
389 static void gtk_sheet_unrealize (GtkWidget
* widget
);
390 static void gtk_sheet_map (GtkWidget
* widget
);
391 static void gtk_sheet_unmap (GtkWidget
* widget
);
392 static gint
gtk_sheet_expose (GtkWidget
* widget
,
393 GdkEventExpose
* event
);
394 static void gtk_sheet_forall (GtkContainer
*container
,
395 gboolean include_internals
,
396 GtkCallback callback
,
397 gpointer callback_data
);
399 static void gtk_sheet_set_scroll_adjustments (GtkSheet
*sheet
,
400 GtkAdjustment
*hadjustment
,
401 GtkAdjustment
*vadjustment
);
403 static gint
gtk_sheet_button_press (GtkWidget
* widget
,
404 GdkEventButton
* event
);
405 static gint
gtk_sheet_button_release (GtkWidget
* widget
,
406 GdkEventButton
* event
);
407 static gint
gtk_sheet_motion (GtkWidget
* widget
,
408 GdkEventMotion
* event
);
411 static gint
gtk_sheet_entry_key_press (GtkWidget
*widget
,
415 static gint
gtk_sheet_key_press (GtkWidget
*widget
,
418 static void gtk_sheet_size_request (GtkWidget
* widget
,
419 GtkRequisition
* requisition
);
420 static void gtk_sheet_size_allocate (GtkWidget
* widget
,
421 GtkAllocation
* allocation
);
425 static gint
gtk_sheet_range_isvisible (GtkSheet
* sheet
,
426 GtkSheetRange range
);
427 static gint
gtk_sheet_cell_isvisible (GtkSheet
* sheet
,
428 gint row
, gint column
);
431 static gint
gtk_sheet_scroll (gpointer data
);
432 static gint
gtk_sheet_flash (gpointer data
);
434 /* Drawing Routines */
436 /* draw cell background and frame */
437 static void gtk_sheet_cell_draw_default (GtkSheet
*sheet
,
438 gint row
, gint column
);
440 /* draw cell border */
441 static void gtk_sheet_cell_draw_border (GtkSheet
*sheet
,
442 gint row
, gint column
,
445 /* draw cell contents */
446 static void gtk_sheet_cell_draw_label (GtkSheet
*sheet
,
447 gint row
, gint column
);
449 /* draw visible part of range. If range==NULL then draw the whole screen */
450 static void gtk_sheet_range_draw (GtkSheet
*sheet
,
451 const GtkSheetRange
*range
);
453 /* highlight the visible part of the selected range */
454 static void gtk_sheet_range_draw_selection (GtkSheet
*sheet
,
455 GtkSheetRange range
);
459 static gint
gtk_sheet_move_query (GtkSheet
*sheet
,
460 gint row
, gint column
);
461 static void gtk_sheet_real_select_range (GtkSheet
* sheet
,
462 GtkSheetRange
* range
);
463 static void gtk_sheet_real_unselect_range (GtkSheet
* sheet
,
464 const GtkSheetRange
* range
);
465 static void gtk_sheet_extend_selection (GtkSheet
*sheet
,
466 gint row
, gint column
);
467 static void gtk_sheet_new_selection (GtkSheet
*sheet
,
468 GtkSheetRange
*range
);
469 static void gtk_sheet_draw_border (GtkSheet
*sheet
,
470 GtkSheetRange range
);
471 static void gtk_sheet_draw_corners (GtkSheet
*sheet
,
472 GtkSheetRange range
);
475 /* Active Cell handling */
477 static void gtk_sheet_entry_changed (GtkWidget
*widget
,
479 static gboolean
gtk_sheet_deactivate_cell (GtkSheet
*sheet
);
480 static void gtk_sheet_hide_active_cell (GtkSheet
*sheet
);
481 static gboolean
gtk_sheet_activate_cell (GtkSheet
*sheet
,
483 static void gtk_sheet_draw_active_cell (GtkSheet
*sheet
);
484 static void gtk_sheet_show_active_cell (GtkSheet
*sheet
);
485 static void gtk_sheet_click_cell (GtkSheet
*sheet
,
492 static void gtk_sheet_make_backing_pixmap (GtkSheet
*sheet
,
493 guint width
, guint height
);
494 static void gtk_sheet_draw_backing_pixmap (GtkSheet
*sheet
,
495 GtkSheetRange range
);
498 static void adjust_scrollbars (GtkSheet
* sheet
);
499 static void vadjustment_changed (GtkAdjustment
* adjustment
,
501 static void hadjustment_changed (GtkAdjustment
* adjustment
,
503 static void vadjustment_value_changed (GtkAdjustment
* adjustment
,
505 static void hadjustment_value_changed (GtkAdjustment
* adjustment
,
509 static void draw_xor_vline (GtkSheet
* sheet
);
510 static void draw_xor_hline (GtkSheet
* sheet
);
511 static void draw_xor_rectangle (GtkSheet
*sheet
,
512 GtkSheetRange range
);
513 static void gtk_sheet_draw_flashing_range (GtkSheet
*sheet
,
514 GtkSheetRange range
);
515 static guint
new_column_width (GtkSheet
* sheet
,
518 static guint
new_row_height (GtkSheet
* sheet
,
523 static void create_global_button (GtkSheet
*sheet
);
524 static void global_button_clicked (GtkWidget
*widget
,
528 static void create_sheet_entry (GtkSheet
*sheet
);
529 static void gtk_sheet_size_allocate_entry (GtkSheet
*sheet
);
531 /* Sheet button gadgets */
533 static void size_allocate_column_title_buttons (GtkSheet
* sheet
);
534 static void size_allocate_row_title_buttons (GtkSheet
* sheet
);
535 static void gtk_sheet_recalc_top_ypixels (GtkSheet
*sheet
,
537 static void gtk_sheet_recalc_left_xpixels (GtkSheet
*sheet
,
539 static void row_button_set (GtkSheet
*sheet
,
541 static void column_button_set (GtkSheet
*sheet
,
543 static void row_button_release (GtkSheet
*sheet
,
545 static void column_button_release (GtkSheet
*sheet
,
547 static void gtk_sheet_button_draw (GtkSheet
*sheet
,
548 gint row
, gint column
);
549 static void size_allocate_global_button (GtkSheet
*sheet
);
550 static void gtk_sheet_button_size_request (GtkSheet
*sheet
,
551 GtkSheetButton
*button
,
552 GtkRequisition
*requisition
);
554 /* Attributes routines */
556 static void gtk_sheet_set_cell_attributes (GtkSheet
*sheet
,
558 GtkSheetCellAttr attributes
);
560 static void init_attributes (GtkSheet
*sheet
, gint col
,
561 GtkSheetCellAttr
*attributes
);
562 /* Memory allocation routines */
563 static void gtk_sheet_real_range_clear (GtkSheet
*sheet
,
564 const GtkSheetRange
*range
,
566 static void gtk_sheet_real_cell_clear (GtkSheet
*sheet
,
570 static GtkSheetCell
* gtk_sheet_cell_new (void);
571 static gint
AddRow (GtkSheet
*sheet
, gint nrows
);
572 static gint
AddColumn (GtkSheet
*sheet
, gint ncols
);
573 static gint
InsertRow (GtkSheet
*sheet
, gint row
, gint nrows
);
574 static gint
InsertColumn (GtkSheet
*sheet
, gint col
, gint ncols
);
575 static gint
DeleteRow (GtkSheet
*sheet
, gint row
, gint nrows
);
576 static gint
DeleteColumn (GtkSheet
*sheet
, gint col
, gint ncols
);
577 static gint
GrowSheet (GtkSheet
*sheet
,
578 gint newrows
, gint newcols
);
579 static gint
CheckBounds (GtkSheet
*sheet
,
582 /* Container Functions */
583 static void gtk_sheet_remove (GtkContainer
*container
,
585 static void gtk_sheet_realize_child (GtkSheet
*sheet
,
586 GtkSheetChild
*child
);
587 static void gtk_sheet_position_child (GtkSheet
*sheet
,
588 GtkSheetChild
*child
);
589 static void gtk_sheet_position_children (GtkSheet
*sheet
);
590 static void gtk_sheet_child_show (GtkSheetChild
*child
);
591 static void gtk_sheet_child_hide (GtkSheetChild
*child
);
592 static void gtk_sheet_column_size_request (GtkSheet
*sheet
,
595 static void gtk_sheet_row_size_request (GtkSheet
*sheet
,
602 /* \brief Imported from gtkextra.c by SDB 7.22.2004
606 _gtkextra_signal_emit(GtkObject
*object
, guint signal_id
, ...)
610 GValue instance_and_params
[10] = { {0, }, };
616 va_start (var_args
, signal_id
);
618 g_value_init(instance_and_params
+ 0, GTK_OBJECT_TYPE(object
));
619 g_value_set_instance (instance_and_params
+ 0, G_OBJECT(object
));
621 g_signal_query(signal_id
, &query
);
623 for (i
= 0; i
< query
.n_params
; i
++)
625 gboolean static_scope
= query
.param_types
[i
]&~G_SIGNAL_TYPE_STATIC_SCOPE
;
626 g_value_init(instance_and_params
+ i
+ 1, query
.param_types
[i
]);
629 G_VALUE_COLLECT (instance_and_params
+ i
+ 1,
631 static_scope
? G_VALUE_NOCOPY_CONTENTS
: 0,
636 g_warning ("%s: %s", G_STRLOC
, error
);
639 g_value_unset (instance_and_params
+ i
);
648 g_value_init(&ret
, query
.return_type
);
649 result
= va_arg(var_args
,gboolean
*);
650 g_value_set_boolean(&ret
, *result
);
651 g_signal_emitv(instance_and_params
, signal_id
, 0, &ret
);
652 *result
= g_value_get_boolean(&ret
);
653 g_value_unset (&ret
);
655 for (i
= 0; i
< query
.n_params
; i
++)
656 g_value_unset (instance_and_params
+ 1 + i
);
657 g_value_unset (instance_and_params
+ 0);
681 static GtkContainerClass
*parent_class
= NULL
;
682 static guint sheet_signals
[LAST_SIGNAL
] = {0};
686 gtk_sheet_get_type ()
688 static GType sheet_type
= 0;
692 static const GTypeInfo sheet_info
=
694 sizeof (GtkSheetClass
),
697 (GClassInitFunc
) gtk_sheet_class_init
,
702 (GInstanceInitFunc
) gtk_sheet_init
,
706 g_type_register_static (GTK_TYPE_CONTAINER
, "GtkSheet",
712 static GtkSheetRange
*
713 gtk_sheet_range_copy (const GtkSheetRange
*range
)
715 GtkSheetRange
*new_range
;
717 g_return_val_if_fail (range
!= NULL
, NULL
);
719 new_range
= g_new (GtkSheetRange
, 1);
727 gtk_sheet_range_free (GtkSheetRange
*range
)
729 g_return_if_fail (range
!= NULL
);
735 gtk_sheet_range_get_type (void)
737 static GType sheet_range_type
;
739 if(!sheet_range_type
)
741 sheet_range_type
= g_boxed_type_register_static("GtkSheetRange", (GBoxedCopyFunc
)gtk_sheet_range_copy
, (GBoxedFreeFunc
)gtk_sheet_range_free
);
743 return sheet_range_type
;
748 gtk_sheet_class_init (GtkSheetClass
* klass
)
750 GtkObjectClass
*object_class
;
751 GtkWidgetClass
*widget_class
;
752 GtkContainerClass
*container_class
;
753 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
755 object_class
= (GtkObjectClass
*) klass
;
756 widget_class
= (GtkWidgetClass
*) klass
;
757 container_class
= (GtkContainerClass
*) klass
;
759 parent_class
= g_type_class_peek_parent (klass
);
761 sheet_signals
[SELECT_ROW
] =
762 gtk_signal_new ("select_row",
764 GTK_CLASS_TYPE(object_class
),
765 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_row
),
767 GTK_TYPE_NONE
, 1, GTK_TYPE_INT
);
769 sheet_signals
[SELECT_COLUMN
] =
770 gtk_signal_new ("select_column",
772 GTK_CLASS_TYPE(object_class
),
773 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_column
),
775 GTK_TYPE_NONE
, 1, GTK_TYPE_INT
);
777 sheet_signals
[SELECT_RANGE
] =
778 gtk_signal_new ("select_range",
780 GTK_CLASS_TYPE(object_class
),
781 GTK_SIGNAL_OFFSET (GtkSheetClass
, select_range
),
782 gtkextra_VOID__BOXED
,
783 GTK_TYPE_NONE
, 1, GTK_TYPE_SHEET_RANGE
);
785 sheet_signals
[CLIP_RANGE
] =
786 gtk_signal_new ("clip_range",
788 GTK_CLASS_TYPE(object_class
),
789 GTK_SIGNAL_OFFSET (GtkSheetClass
, clip_range
),
790 gtkextra_VOID__BOXED
,
791 GTK_TYPE_NONE
, 1, GTK_TYPE_SHEET_RANGE
);
793 sheet_signals
[RESIZE_RANGE
] =
794 gtk_signal_new ("resize_range",
796 GTK_CLASS_TYPE(object_class
),
797 GTK_SIGNAL_OFFSET (GtkSheetClass
, resize_range
),
798 gtkextra_VOID__BOXED_BOXED
,
799 GTK_TYPE_NONE
, 2, GTK_TYPE_SHEET_RANGE
, GTK_TYPE_SHEET_RANGE
);
800 sheet_signals
[MOVE_RANGE
] =
801 gtk_signal_new ("move_range",
803 GTK_CLASS_TYPE(object_class
),
804 GTK_SIGNAL_OFFSET (GtkSheetClass
, move_range
),
805 gtkextra_VOID__BOXED_BOXED
,
806 GTK_TYPE_NONE
, 2, GTK_TYPE_SHEET_RANGE
, GTK_TYPE_SHEET_RANGE
);
807 sheet_signals
[TRAVERSE
] =
808 gtk_signal_new ("traverse",
810 GTK_CLASS_TYPE(object_class
),
811 GTK_SIGNAL_OFFSET (GtkSheetClass
, traverse
),
812 gtkextra_BOOLEAN__INT_INT_POINTER_POINTER
,
813 GTK_TYPE_BOOL
, 4, GTK_TYPE_INT
, GTK_TYPE_INT
,
814 GTK_TYPE_POINTER
, GTK_TYPE_POINTER
);
816 sheet_signals
[DEACTIVATE
] =
817 gtk_signal_new ("deactivate",
819 GTK_CLASS_TYPE(object_class
),
820 GTK_SIGNAL_OFFSET (GtkSheetClass
, deactivate
),
821 gtkextra_BOOLEAN__INT_INT
,
822 GTK_TYPE_BOOL
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
824 sheet_signals
[ACTIVATE
] =
825 gtk_signal_new ("activate",
827 GTK_CLASS_TYPE(object_class
),
828 GTK_SIGNAL_OFFSET (GtkSheetClass
, activate
),
829 gtkextra_BOOLEAN__INT_INT
,
830 GTK_TYPE_BOOL
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
832 sheet_signals
[SET_CELL
] =
833 gtk_signal_new ("set_cell",
835 GTK_CLASS_TYPE(object_class
),
836 GTK_SIGNAL_OFFSET (GtkSheetClass
, set_cell
),
837 gtkextra_VOID__INT_INT
,
838 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
840 sheet_signals
[CLEAR_CELL
] =
841 gtk_signal_new ("clear_cell",
843 GTK_CLASS_TYPE(object_class
),
844 GTK_SIGNAL_OFFSET (GtkSheetClass
, clear_cell
),
845 gtkextra_VOID__INT_INT
,
846 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
848 sheet_signals
[CHANGED
] =
849 gtk_signal_new ("changed",
851 GTK_CLASS_TYPE(object_class
),
852 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
853 gtkextra_VOID__INT_INT
,
854 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
856 sheet_signals
[NEW_COL_WIDTH
] =
857 gtk_signal_new ("new_column_width",
859 GTK_CLASS_TYPE(object_class
),
860 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
861 gtkextra_VOID__INT_INT
,
862 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
864 sheet_signals
[NEW_ROW_HEIGHT
] =
865 gtk_signal_new ("new_row_height",
867 GTK_CLASS_TYPE(object_class
),
868 GTK_SIGNAL_OFFSET (GtkSheetClass
, changed
),
869 gtkextra_VOID__INT_INT
,
870 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
);
874 widget_class
->set_scroll_adjustments_signal
=
875 gtk_signal_new ("set_scroll_adjustments",
877 GTK_CLASS_TYPE(object_class
),
878 GTK_SIGNAL_OFFSET (GtkSheetClass
, set_scroll_adjustments
),
879 gtkextra_VOID__OBJECT_OBJECT
,
880 GTK_TYPE_NONE
, 2, GTK_TYPE_ADJUSTMENT
, GTK_TYPE_ADJUSTMENT
);
883 container_class
->add
= NULL
;
884 container_class
->remove
= gtk_sheet_remove
;
885 container_class
->forall
= gtk_sheet_forall
;
887 object_class
->destroy
= gtk_sheet_destroy
;
888 gobject_class
->finalize
= gtk_sheet_finalize
;
890 widget_class
->realize
= gtk_sheet_realize
;
891 widget_class
->unrealize
= gtk_sheet_unrealize
;
892 widget_class
->map
= gtk_sheet_map
;
893 widget_class
->unmap
= gtk_sheet_unmap
;
894 widget_class
->style_set
= gtk_sheet_style_set
;
895 widget_class
->button_press_event
= gtk_sheet_button_press
;
896 widget_class
->button_release_event
= gtk_sheet_button_release
;
897 widget_class
->motion_notify_event
= gtk_sheet_motion
;
898 widget_class
->key_press_event
= gtk_sheet_key_press
;
899 widget_class
->expose_event
= gtk_sheet_expose
;
900 widget_class
->size_request
= gtk_sheet_size_request
;
901 widget_class
->size_allocate
= gtk_sheet_size_allocate
;
902 widget_class
->focus_in_event
= NULL
;
903 widget_class
->focus_out_event
= NULL
;
905 klass
->set_scroll_adjustments
= gtk_sheet_set_scroll_adjustments
;
906 klass
->select_row
= NULL
;
907 klass
->select_column
= NULL
;
908 klass
->select_range
= NULL
;
909 klass
->clip_range
= NULL
;
910 klass
->resize_range
= NULL
;
911 klass
->move_range
= NULL
;
912 klass
->traverse
= NULL
;
913 klass
->deactivate
= NULL
;
914 klass
->activate
= NULL
;
915 klass
->set_cell
= NULL
;
916 klass
->clear_cell
= NULL
;
917 klass
->changed
= NULL
;
919 gtk_widget_class_install_style_property (widget_class
,
920 g_param_spec_boxed ("default-border",
921 NULL
, /* P_("Default Spacing"),*/
922 NULL
, /* P_("Extra space to add for CAN_DEFAULT buttons"), */
926 gtk_widget_class_install_style_property (widget_class
,
927 g_param_spec_boxed ("default-outside-border",
928 NULL
, /* P_("Default Outside Spacing"), */
929 NULL
, /* P_("Extra space to add for CAN_DEFAULT buttons that is always drawn outside the border"), */
935 gtk_sheet_init (GtkSheet
*sheet
)
937 sheet
->children
= NULL
;
940 sheet
->selection_mode
= GTK_SELECTION_BROWSE
;
941 sheet
->freeze_count
= 0;
942 sheet
->state
= GTK_SHEET_NORMAL
;
944 GTK_WIDGET_UNSET_FLAGS (sheet
, GTK_NO_WINDOW
);
945 GTK_WIDGET_SET_FLAGS (sheet
, GTK_CAN_FOCUS
);
950 sheet
->view
.row0
= 0;
951 sheet
->view
.col0
= 0;
952 sheet
->view
.rowi
= 0;
953 sheet
->view
.coli
= 0;
955 sheet
->maxallocrow
= 0;
956 sheet
->maxalloccol
= 0;
958 sheet
->column_title_window
=NULL
;
959 sheet
->column_title_area
.x
=0;
960 sheet
->column_title_area
.y
=0;
961 sheet
->column_title_area
.width
=0;
962 sheet
->column_title_area
.height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
964 sheet
->row_title_window
=NULL
;
965 sheet
->row_title_area
.x
=0;
966 sheet
->row_title_area
.y
=0;
967 sheet
->row_title_area
.width
=DEFAULT_COLUMN_WIDTH
;
968 sheet
->row_title_area
.height
=0;
970 sheet
->active_cell
.row
=0;
971 sheet
->active_cell
.col
=0;
972 sheet
->selection_cell
.row
=0;
973 sheet
->selection_cell
.col
=0;
975 sheet
->sheet_entry
=NULL
;
983 sheet
->state
=GTK_SHEET_NORMAL
;
985 sheet
->sheet_window
= NULL
;
986 sheet
->sheet_window_width
= 0;
987 sheet
->sheet_window_height
= 0;
988 sheet
->sheet_entry
= NULL
;
989 sheet
->button
= NULL
;
994 sheet
->hadjustment
= NULL
;
995 sheet
->vadjustment
= NULL
;
997 sheet
->cursor_drag
= gdk_cursor_new(GDK_PLUS
);
998 sheet
->xor_gc
= NULL
;
1000 sheet
->bg_gc
= NULL
;
1004 gdk_color_white(gdk_colormap_get_system(), &sheet
->bg_color
);
1005 gdk_color_parse("gray", &sheet
->grid_color
);
1006 gdk_color_alloc(gdk_colormap_get_system(), &sheet
->grid_color
);
1007 sheet
->show_grid
= TRUE
;
1011 gtk_sheet_new (guint rows
, guint columns
, const gchar
*title
)
1016 g_return_val_if_fail (columns
>= MINCOLS
, NULL
);
1017 g_return_val_if_fail (rows
>= MINROWS
, NULL
);
1019 widget
= gtk_type_new (gtk_sheet_get_type ());
1021 gtk_sheet_construct(GTK_SHEET(widget
), rows
, columns
, title
);
1027 gtk_sheet_construct (GtkSheet
*sheet
, guint rows
, guint columns
, const gchar
*title
)
1029 sheet
->row
=(GtkSheetRow
*)g_malloc(sizeof(GtkSheetRow
));
1030 sheet
->column
=(GtkSheetColumn
*)g_malloc(sizeof(GtkSheetColumn
));
1031 sheet
->data
=(GtkSheetCell
***)g_malloc(sizeof(GtkSheetCell
**));
1033 sheet
->data
[0] = (GtkSheetCell
**)g_malloc(sizeof(GtkSheetCell
*)+sizeof(gdouble
));
1034 sheet
->data
[0][0] = NULL
;
1036 sheet
->columns_resizable
= TRUE
;
1037 sheet
->rows_resizable
= TRUE
;
1038 sheet
->row_titles_visible
= TRUE
;
1039 sheet
->column_titles_visible
= TRUE
;
1040 sheet
->autoscroll
= TRUE
;
1041 sheet
->justify_entry
= TRUE
;
1042 sheet
->locked
= FALSE
;
1044 /* set number of rows and columns */
1045 GrowSheet(sheet
, MINROWS
, MINCOLS
);
1047 /* Init row an column zero */
1049 AddColumn(sheet
,-1);
1051 /* Add rows and columns */
1052 AddRow(sheet
,rows
-1);
1053 AddColumn(sheet
,columns
-1);
1055 /* create sheet entry */
1056 sheet
->entry_type
= 0;
1057 create_sheet_entry (sheet
);
1059 /* create global selection button */
1060 create_global_button(sheet
);
1063 sheet
->name
= g_strdup(title
);
1069 gtk_sheet_new_browser(guint rows
, guint columns
, const gchar
*title
)
1073 widget
= gtk_type_new (gtk_sheet_get_type ());
1075 gtk_sheet_construct_browser(GTK_SHEET(widget
), rows
, columns
, title
);
1081 gtk_sheet_construct_browser(GtkSheet
*sheet
, guint rows
, guint columns
,
1084 gtk_sheet_construct(sheet
, rows
, columns
, title
);
1086 gtk_sheet_set_locked(sheet
, TRUE
);
1087 sheet
->autoresize
= TRUE
;
1091 gtk_sheet_new_with_custom_entry (guint rows
, guint columns
, const gchar
*title
,
1096 widget
= gtk_type_new (gtk_sheet_get_type ());
1098 gtk_sheet_construct_with_custom_entry(GTK_SHEET(widget
),
1099 rows
, columns
, title
, entry_type
);
1105 gtk_sheet_construct_with_custom_entry (GtkSheet
*sheet
,
1106 guint rows
, guint columns
,
1110 gtk_sheet_construct(sheet
, rows
, columns
, title
);
1112 sheet
->entry_type
= entry_type
;
1113 create_sheet_entry(sheet
);
1118 gtk_sheet_change_entry(GtkSheet
*sheet
, GtkType entry_type
)
1122 g_return_if_fail (sheet
!= NULL
);
1123 g_return_if_fail (GTK_IS_SHEET (sheet
));
1125 state
= sheet
->state
;
1127 if(sheet
->state
== GTK_SHEET_NORMAL
)
1128 gtk_sheet_hide_active_cell(sheet
);
1130 sheet
->entry_type
= entry_type
;
1132 create_sheet_entry(sheet
);
1134 if(state
== GTK_SHEET_NORMAL
)
1136 gtk_sheet_show_active_cell(sheet
);
1137 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
1139 (GtkSignalFunc
)gtk_sheet_entry_changed
,
1140 GTK_OBJECT(GTK_WIDGET(sheet
)));
1146 gtk_sheet_show_grid(GtkSheet
*sheet
, gboolean show
)
1148 g_return_if_fail (sheet
!= NULL
);
1149 g_return_if_fail (GTK_IS_SHEET (sheet
));
1151 if(show
== sheet
->show_grid
) return;
1153 sheet
->show_grid
= show
;
1155 if(!GTK_SHEET_IS_FROZEN(sheet
))
1156 gtk_sheet_range_draw(sheet
, NULL
);
1160 gtk_sheet_grid_visible(GtkSheet
*sheet
)
1162 g_return_val_if_fail (sheet
!= NULL
, 0);
1163 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1165 return sheet
->show_grid
;
1169 gtk_sheet_set_background(GtkSheet
*sheet
, GdkColor
*color
)
1171 g_return_if_fail (sheet
!= NULL
);
1172 g_return_if_fail (GTK_IS_SHEET (sheet
));
1175 gdk_color_white(gdk_colormap_get_system(), &sheet
->bg_color
);
1177 sheet
->bg_color
= *color
;
1179 if(!GTK_SHEET_IS_FROZEN(sheet
))
1180 gtk_sheet_range_draw(sheet
, NULL
);
1184 gtk_sheet_set_grid(GtkSheet
*sheet
, GdkColor
*color
)
1186 g_return_if_fail (sheet
!= NULL
);
1187 g_return_if_fail (GTK_IS_SHEET (sheet
));
1190 gdk_color_black(gdk_colormap_get_system(), &sheet
->grid_color
);
1192 sheet
->grid_color
= *color
;
1194 if(!GTK_SHEET_IS_FROZEN(sheet
))
1195 gtk_sheet_range_draw(sheet
, NULL
);
1199 gtk_sheet_get_columns_count(GtkSheet
*sheet
)
1201 g_return_val_if_fail (sheet
!= NULL
, 0);
1202 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1204 return sheet
->maxcol
+ 1;
1208 gtk_sheet_get_rows_count(GtkSheet
*sheet
)
1210 g_return_val_if_fail (sheet
!= NULL
, 0);
1211 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1213 return sheet
->maxrow
+ 1;
1217 gtk_sheet_get_state(GtkSheet
*sheet
)
1219 g_return_val_if_fail (sheet
!= NULL
, 0);
1220 g_return_val_if_fail (GTK_IS_SHEET (sheet
), 0);
1222 return (sheet
->state
);
1226 gtk_sheet_set_selection_mode(GtkSheet
*sheet
, gint mode
)
1228 g_return_if_fail (sheet
!= NULL
);
1229 g_return_if_fail (GTK_IS_SHEET (sheet
));
1231 if(GTK_WIDGET_REALIZED(sheet
))
1232 gtk_sheet_real_unselect_range(sheet
, NULL
);
1234 sheet
->selection_mode
= mode
;
1238 gtk_sheet_set_autoresize (GtkSheet
*sheet
, gboolean autoresize
)
1240 g_return_if_fail (sheet
!= NULL
);
1241 g_return_if_fail (GTK_IS_SHEET (sheet
));
1243 sheet
->autoresize
= autoresize
;
1247 gtk_sheet_autoresize (GtkSheet
*sheet
)
1249 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1250 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1252 return sheet
->autoresize
;
1256 gtk_sheet_set_autoscroll (GtkSheet
*sheet
, gboolean autoscroll
)
1258 g_return_if_fail (sheet
!= NULL
);
1259 g_return_if_fail (GTK_IS_SHEET (sheet
));
1261 sheet
->autoscroll
= autoscroll
;
1265 gtk_sheet_autoscroll (GtkSheet
*sheet
)
1267 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1268 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1270 return sheet
->autoscroll
;
1274 gtk_sheet_set_clip_text (GtkSheet
*sheet
, gboolean clip_text
)
1276 g_return_if_fail (sheet
!= NULL
);
1277 g_return_if_fail (GTK_IS_SHEET (sheet
));
1279 sheet
->clip_text
= clip_text
;
1283 gtk_sheet_clip_text (GtkSheet
*sheet
)
1285 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1286 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1288 return sheet
->clip_text
;
1292 gtk_sheet_set_justify_entry (GtkSheet
*sheet
, gboolean justify
)
1294 g_return_if_fail (sheet
!= NULL
);
1295 g_return_if_fail (GTK_IS_SHEET (sheet
));
1297 sheet
->justify_entry
= justify
;
1301 gtk_sheet_justify_entry (GtkSheet
*sheet
)
1303 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1304 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1306 return sheet
->justify_entry
;
1310 gtk_sheet_set_locked (GtkSheet
*sheet
, gboolean locked
)
1312 g_return_if_fail (sheet
!= NULL
);
1313 g_return_if_fail (GTK_IS_SHEET (sheet
));
1315 sheet
->locked
= locked
;
1319 gtk_sheet_locked (GtkSheet
*sheet
)
1321 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1322 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1324 return sheet
->locked
;
1327 /* This routine has problems with gtk+-1.2 related with the
1328 * label/button drawing - I think it's a bug in gtk+-1.2 */
1331 gtk_sheet_set_title(GtkSheet
*sheet
, const gchar
*title
)
1333 /* GtkWidget *old_widget;
1334 */ GtkWidget
*label
;
1336 g_return_if_fail (sheet
!= NULL
);
1337 g_return_if_fail (title
!= NULL
);
1338 g_return_if_fail (GTK_IS_SHEET (sheet
));
1341 g_free (sheet
->name
);
1343 sheet
->name
= g_strdup (title
);
1345 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) || !title
) return;
1347 if(GTK_BIN(sheet
->button
)->child
)
1348 label
= GTK_BIN(sheet
->button
)->child
;
1350 gtk_label_set_text(GTK_LABEL(label), title);
1352 size_allocate_global_button(sheet
);
1354 /* remove and destroy the old widget */
1356 old_widget = GTK_BIN (sheet->button)->child;
1359 gtk_container_remove (GTK_CONTAINER (sheet->button), old_widget);
1362 label = gtk_label_new (title);
1363 gtk_misc_set_alignment(GTK_MISC(label), 0.5 , 0.5 );
1365 gtk_container_add (GTK_CONTAINER (sheet->button), label);
1366 gtk_widget_show (label);
1368 size_allocate_global_button(sheet);
1370 gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], -1, -1);
1373 gtk_widget_destroy (old_widget);
1378 gtk_sheet_freeze (GtkSheet
*sheet
)
1380 g_return_if_fail (sheet
!= NULL
);
1381 g_return_if_fail (GTK_IS_SHEET (sheet
));
1383 sheet
->freeze_count
++;
1384 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
1388 gtk_sheet_thaw(GtkSheet
*sheet
)
1390 g_return_if_fail (sheet
!= NULL
);
1391 g_return_if_fail (GTK_IS_SHEET (sheet
));
1393 if(sheet
->freeze_count
== 0) return;
1395 sheet
->freeze_count
--;
1396 if(sheet
->freeze_count
> 0) return;
1398 adjust_scrollbars(sheet
);
1400 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
1402 sheet
->old_vadjustment
= -1.;
1403 sheet
->old_hadjustment
= -1.;
1405 if(sheet
->hadjustment
)
1406 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1408 if(sheet
->vadjustment
)
1409 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1412 if(sheet
->state
== GTK_STATE_NORMAL
)
1413 if(sheet
->sheet_entry
&& GTK_WIDGET_MAPPED(sheet
->sheet_entry
)){
1414 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
);
1416 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet)),
1418 (GtkSignalFunc)gtk_sheet_entry_changed,
1419 GTK_OBJECT(GTK_WIDGET(sheet)));
1420 gtk_sheet_show_active_cell(sheet);
1427 gtk_sheet_set_row_titles_width(GtkSheet
*sheet
, guint width
)
1429 if(width
< COLUMN_MIN_WIDTH
) return;
1431 sheet
->row_title_area
.width
= width
;
1432 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
1433 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
1434 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1435 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1436 adjust_scrollbars(sheet
);
1438 sheet
->old_hadjustment
= -1.;
1439 if(sheet
->hadjustment
)
1440 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1442 size_allocate_global_button(sheet
);
1446 gtk_sheet_set_column_titles_height(GtkSheet
*sheet
, guint height
)
1448 if(height
< DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))) return;
1450 sheet
->column_title_area
.height
= height
;
1451 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
1452 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
1453 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1454 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1455 adjust_scrollbars(sheet
);
1457 sheet
->old_vadjustment
= -1.;
1458 if(sheet
->vadjustment
)
1459 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1461 size_allocate_global_button(sheet
);
1465 gtk_sheet_show_column_titles(GtkSheet
*sheet
)
1469 if(sheet
->column_titles_visible
) return;
1471 sheet
->column_titles_visible
= TRUE
;
1472 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1473 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1474 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1475 gdk_window_show(sheet
->column_title_window
);
1476 gdk_window_move_resize (sheet
->column_title_window
,
1477 sheet
->column_title_area
.x
,
1478 sheet
->column_title_area
.y
,
1479 sheet
->column_title_area
.width
,
1480 sheet
->column_title_area
.height
);
1482 for(col
= MIN_VISIBLE_COLUMN(sheet
); col
<= MAX_VISIBLE_COLUMN(sheet
); col
++){
1483 GtkSheetChild
*child
;
1484 child
= sheet
->column
[col
].button
.child
;
1486 gtk_sheet_child_show(child
);
1489 adjust_scrollbars(sheet
);
1492 sheet
->old_vadjustment
= -1.;
1493 if(sheet
->vadjustment
)
1494 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1496 size_allocate_global_button(sheet
);
1500 gtk_sheet_show_row_titles(GtkSheet
*sheet
)
1504 if(sheet
->row_titles_visible
) return;
1506 sheet
->row_titles_visible
= TRUE
;
1507 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1508 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1509 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1510 gdk_window_show(sheet
->row_title_window
);
1511 gdk_window_move_resize (sheet
->row_title_window
,
1512 sheet
->row_title_area
.x
,
1513 sheet
->row_title_area
.y
,
1514 sheet
->row_title_area
.width
,
1515 sheet
->row_title_area
.height
);
1517 for(row
= MIN_VISIBLE_ROW(sheet
); row
<= MAX_VISIBLE_ROW(sheet
); row
++){
1518 GtkSheetChild
*child
;
1519 child
= sheet
->row
[row
].button
.child
;
1521 gtk_sheet_child_show(child
);
1524 adjust_scrollbars(sheet
);
1527 sheet
->old_hadjustment
= -1.;
1528 if(sheet
->hadjustment
)
1529 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1531 size_allocate_global_button(sheet
);
1535 gtk_sheet_hide_column_titles(GtkSheet
*sheet
)
1539 if(!sheet
->column_titles_visible
) return;
1541 sheet
->column_titles_visible
= FALSE
;
1542 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1543 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1544 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1545 if(sheet
->column_title_window
)
1546 gdk_window_hide(sheet
->column_title_window
);
1547 if(GTK_WIDGET_VISIBLE(sheet
->button
))
1548 gtk_widget_hide(sheet
->button
);
1550 for(col
= MIN_VISIBLE_COLUMN(sheet
); col
<= MAX_VISIBLE_COLUMN(sheet
); col
++){
1551 GtkSheetChild
*child
;
1552 child
= sheet
->column
[col
].button
.child
;
1554 gtk_sheet_child_hide(child
);
1557 adjust_scrollbars(sheet
);
1560 sheet
->old_vadjustment
= -1.;
1561 if(sheet
->vadjustment
)
1562 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1567 gtk_sheet_hide_row_titles(GtkSheet
*sheet
)
1571 if(!sheet
->row_titles_visible
) return;
1573 sheet
->row_titles_visible
= FALSE
;
1574 gtk_sheet_recalc_top_ypixels(sheet
, 0);
1575 gtk_sheet_recalc_left_xpixels(sheet
, 0);
1576 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
1577 if(sheet
->row_title_window
)
1578 gdk_window_hide(sheet
->row_title_window
);
1579 if(GTK_WIDGET_VISIBLE(sheet
->button
))
1580 gtk_widget_hide(sheet
->button
);
1581 for(row
= MIN_VISIBLE_ROW(sheet
); row
<= MAX_VISIBLE_ROW(sheet
); row
++){
1582 GtkSheetChild
*child
;
1583 child
= sheet
->row
[row
].button
.child
;
1585 gtk_sheet_child_hide(child
);
1588 adjust_scrollbars(sheet
);
1591 sheet
->old_hadjustment
= -1.;
1592 if(sheet
->hadjustment
)
1593 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1598 gtk_sheet_column_titles_visible(GtkSheet
*sheet
)
1600 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1601 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1602 return sheet
->column_titles_visible
;
1606 gtk_sheet_row_titles_visible(GtkSheet
*sheet
)
1608 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1609 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1610 return sheet
->row_titles_visible
;
1614 gtk_sheet_set_column_title (GtkSheet
* sheet
,
1616 const gchar
* title
)
1618 g_return_if_fail (sheet
!= NULL
);
1619 g_return_if_fail (GTK_IS_SHEET (sheet
));
1621 if (sheet
->column
[column
].name
)
1622 g_free (sheet
->column
[column
].name
);
1624 sheet
->column
[column
].name
= g_strdup(title
);
1628 gtk_sheet_set_row_title (GtkSheet
* sheet
,
1630 const gchar
* title
)
1632 g_return_if_fail (sheet
!= NULL
);
1633 g_return_if_fail (GTK_IS_SHEET (sheet
));
1635 if (sheet
->row
[row
].name
)
1636 g_free (sheet
->row
[row
].name
);
1638 sheet
->row
[row
].name
= g_strdup (title
);
1642 gtk_sheet_get_row_title (GtkSheet
* sheet
,
1645 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1646 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1648 return(sheet
->row
[row
].name
);
1652 gtk_sheet_get_column_title (GtkSheet
* sheet
,
1655 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1656 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1658 return(sheet
->column
[column
].name
);
1662 gtk_sheet_row_button_add_label(GtkSheet
*sheet
, gint row
, const gchar
*label
)
1664 GtkSheetButton
*button
;
1668 g_return_if_fail (sheet
!= NULL
);
1669 g_return_if_fail (GTK_IS_SHEET (sheet
));
1671 if(row
< 0 || row
> sheet
->maxrow
) return;
1673 button
= &sheet
->row
[row
].button
;
1674 if (button
->label
) g_free (button
->label
);
1675 button
->label
= g_strdup (label
);
1677 aux
= gtk_sheet_autoresize(sheet
);
1678 gtk_sheet_set_autoresize(sheet
, TRUE
);
1679 gtk_sheet_button_size_request(sheet
, button
, &req
);
1680 gtk_sheet_set_autoresize(sheet
, aux
);
1682 if(req
.height
> sheet
->row
[row
].height
)
1683 gtk_sheet_set_row_height(sheet
, row
, req
.height
);
1685 if(req
.width
> sheet
->row_title_area
.width
){
1686 gtk_sheet_set_row_titles_width(sheet
, req
.width
);
1689 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1690 gtk_sheet_button_draw(sheet
, row
, -1);
1691 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1696 gtk_sheet_row_button_get_label(GtkSheet
*sheet
, gint row
)
1698 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1699 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1701 if(row
< 0 || row
> sheet
->maxrow
) return NULL
;
1703 return (sheet
->row
[row
].button
.label
);
1707 gtk_sheet_row_label_set_visibility(GtkSheet
*sheet
, gint row
, gboolean visible
)
1709 g_return_if_fail (sheet
!= NULL
);
1710 g_return_if_fail (GTK_IS_SHEET (sheet
));
1712 if(row
< 0 || row
> sheet
->maxrow
) return;
1714 sheet
->row
[row
].button
.label_visible
= visible
;
1716 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1717 gtk_sheet_button_draw(sheet
, row
, -1);
1718 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1723 gtk_sheet_rows_labels_set_visibility(GtkSheet
*sheet
, gboolean visible
)
1727 g_return_if_fail (sheet
!= NULL
);
1728 g_return_if_fail (GTK_IS_SHEET (sheet
));
1730 for(i
= 0; i
<= sheet
->maxrow
; i
++)
1731 gtk_sheet_row_label_set_visibility(sheet
, i
, visible
);
1736 gtk_sheet_column_button_add_label(GtkSheet
*sheet
, gint column
, const gchar
*label
)
1738 GtkSheetButton
*button
;
1742 g_return_if_fail (sheet
!= NULL
);
1743 g_return_if_fail (GTK_IS_SHEET (sheet
));
1745 if(column
< 0 || column
>sheet
->maxcol
) return;
1747 button
= &sheet
->column
[column
].button
;
1748 if (button
->label
) g_free (button
->label
);
1749 button
->label
= g_strdup (label
);
1751 aux
= gtk_sheet_autoresize(sheet
);
1752 gtk_sheet_set_autoresize(sheet
, TRUE
);
1753 gtk_sheet_button_size_request(sheet
, button
, &req
);
1754 gtk_sheet_set_autoresize(sheet
, aux
);
1756 if(req
.width
> sheet
->column
[column
].width
)
1757 gtk_sheet_set_column_width(sheet
, column
, req
.width
);
1759 if(req
.height
> sheet
->column_title_area
.height
)
1760 gtk_sheet_set_column_titles_height(sheet
, req
.height
);
1762 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1763 gtk_sheet_button_draw(sheet
, -1, column
);
1764 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, column
);
1769 gtk_sheet_column_button_get_label(GtkSheet
*sheet
, gint column
)
1771 g_return_val_if_fail (sheet
!= NULL
, NULL
);
1772 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
1774 if(column
< 0 || column
>sheet
->maxcol
) return NULL
;
1776 return(sheet
->column
[column
].button
.label
);
1780 gtk_sheet_column_label_set_visibility(GtkSheet
*sheet
, gint col
, gboolean visible
)
1782 g_return_if_fail (sheet
!= NULL
);
1783 g_return_if_fail (GTK_IS_SHEET (sheet
));
1785 if(col
< 0 || col
> sheet
->maxcol
) return;
1787 sheet
->column
[col
].button
.label_visible
= visible
;
1789 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1790 gtk_sheet_button_draw(sheet
, -1, col
);
1791 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, col
);
1796 gtk_sheet_columns_labels_set_visibility(GtkSheet
*sheet
, gboolean visible
)
1800 g_return_if_fail (sheet
!= NULL
);
1801 g_return_if_fail (GTK_IS_SHEET (sheet
));
1803 for(i
= 0; i
<= sheet
->maxcol
; i
++)
1804 gtk_sheet_column_label_set_visibility(sheet
, i
, visible
);
1808 gtk_sheet_row_button_justify(GtkSheet
*sheet
, gint row
,
1809 GtkJustification justification
)
1811 GtkSheetButton
*button
;
1813 g_return_if_fail (sheet
!= NULL
);
1814 g_return_if_fail (GTK_IS_SHEET (sheet
));
1816 if(row
< 0 || row
> sheet
->maxrow
) return;
1818 button
= &sheet
->row
[row
].button
;
1819 button
->justification
= justification
;
1821 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1822 gtk_sheet_button_draw(sheet
, row
, -1);
1823 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, -1);
1828 gtk_sheet_column_button_justify(GtkSheet
*sheet
, gint column
,
1829 GtkJustification justification
)
1831 GtkSheetButton
*button
;
1833 g_return_if_fail (sheet
!= NULL
);
1834 g_return_if_fail (GTK_IS_SHEET (sheet
));
1836 if(column
< 0 || column
> sheet
->maxcol
) return;
1838 button
= &sheet
->column
[column
].button
;
1839 button
->justification
= justification
;
1841 if(!GTK_SHEET_IS_FROZEN(sheet
)){
1842 gtk_sheet_button_draw(sheet
, -1, column
);
1843 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], -1, column
);
1849 gtk_sheet_moveto (GtkSheet
* sheet
,
1856 guint width
, height
;
1858 gint min_row
, min_col
;
1860 g_return_if_fail (sheet
!= NULL
);
1861 g_return_if_fail (GTK_IS_SHEET (sheet
));
1862 g_return_if_fail (sheet
->hadjustment
!= NULL
);
1863 g_return_if_fail (sheet
->vadjustment
!= NULL
);
1865 if (row
< 0 || row
> sheet
->maxrow
)
1867 if (column
< 0 || column
> sheet
->maxcol
)
1870 height
= sheet
->sheet_window_height
;
1871 width
= sheet
->sheet_window_width
;
1873 /* adjust vertical scrollbar */
1875 if (row
>= 0 && row_align
>=0.)
1877 y
= ROW_TOP_YPIXEL(sheet
, row
) - sheet
->voffset
-
1879 (1.-row_align
)*sheet
->row
[row
].height
;
1881 /* This forces the sheet to scroll when you don't see the entire cell */
1884 if(row_align
== 1.){
1885 while(min_row
>= 0 && min_row
> MIN_VISIBLE_ROW(sheet
)){
1886 if(sheet
->row
[min_row
].is_visible
)
1887 adjust
+= sheet
->row
[min_row
].height
;
1888 if(adjust
>= height
){
1893 min_row
= MAX(min_row
, 0);
1894 y
= ROW_TOP_YPIXEL(sheet
, min_row
) - sheet
->voffset
+
1895 sheet
->row
[min_row
].height
- 1;
1899 sheet
->vadjustment
->value
= 0.0;
1901 sheet
->vadjustment
->value
= y
;
1903 sheet
->old_vadjustment
= -1.;
1904 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
1909 /* adjust horizontal scrollbar */
1910 if (column
>= 0 && col_align
>= 0.)
1912 x
= COLUMN_LEFT_XPIXEL (sheet
, column
) - sheet
->hoffset
-
1914 (1.-col_align
)*sheet
->column
[column
].width
;
1916 /* This forces the sheet to scroll when you don't see the entire cell */
1919 if(col_align
== 1.){
1920 while(min_col
>= 0 && min_col
> MIN_VISIBLE_COLUMN(sheet
)){
1921 if(sheet
->column
[min_col
].is_visible
)
1922 adjust
+= sheet
->column
[min_col
].width
;
1923 if(adjust
>= width
){
1928 min_col
= MAX(min_col
, 0);
1929 x
= COLUMN_LEFT_XPIXEL(sheet
, min_col
) - sheet
->hoffset
+
1930 sheet
->column
[min_col
].width
- 1;
1934 sheet
->hadjustment
->value
= 0.0;
1936 sheet
->hadjustment
->value
= x
;
1938 sheet
->old_vadjustment
= -1.;
1939 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
1946 gtk_sheet_column_set_sensitivity(GtkSheet
*sheet
, gint column
, gboolean sensitive
)
1948 g_return_if_fail (sheet
!= NULL
);
1949 g_return_if_fail (GTK_IS_SHEET (sheet
));
1951 if(column
< 0 || column
> sheet
->maxcol
) return;
1953 sheet
->column
[column
].is_sensitive
=sensitive
;
1955 sheet
->column
[column
].button
.state
=GTK_STATE_INSENSITIVE
;
1957 sheet
->column
[column
].button
.state
=GTK_STATE_NORMAL
;
1959 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
))
1960 gtk_sheet_button_draw(sheet
, -1, column
);
1965 gtk_sheet_columns_set_sensitivity(GtkSheet
*sheet
, gboolean sensitive
)
1969 g_return_if_fail (sheet
!= NULL
);
1970 g_return_if_fail (GTK_IS_SHEET (sheet
));
1972 for(i
=0; i
<=sheet
->maxcol
; i
++)
1973 gtk_sheet_column_set_sensitivity(sheet
, i
, sensitive
);
1977 gtk_sheet_columns_set_resizable (GtkSheet
*sheet
, gboolean resizable
)
1979 g_return_if_fail (sheet
!= NULL
);
1980 g_return_if_fail (GTK_IS_SHEET (sheet
));
1982 sheet
->columns_resizable
= resizable
;
1986 gtk_sheet_columns_resizable (GtkSheet
*sheet
)
1988 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
1989 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
1991 return sheet
->columns_resizable
;
1995 gtk_sheet_row_set_sensitivity(GtkSheet
*sheet
, gint row
, gboolean sensitive
)
1998 g_return_if_fail (sheet
!= NULL
);
1999 g_return_if_fail (GTK_IS_SHEET (sheet
));
2001 if(row
< 0 || row
> sheet
->maxrow
) return;
2003 sheet
->row
[row
].is_sensitive
=sensitive
;
2005 sheet
->row
[row
].button
.state
=GTK_STATE_INSENSITIVE
;
2007 sheet
->row
[row
].button
.state
=GTK_STATE_NORMAL
;
2009 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
))
2010 gtk_sheet_button_draw(sheet
, row
, -1);
2014 gtk_sheet_rows_set_sensitivity(GtkSheet
*sheet
, gboolean sensitive
)
2018 g_return_if_fail (sheet
!= NULL
);
2019 g_return_if_fail (GTK_IS_SHEET (sheet
));
2021 for(i
=0; i
<=sheet
->maxrow
; i
++)
2022 gtk_sheet_row_set_sensitivity(sheet
, i
, sensitive
);
2027 gtk_sheet_rows_set_resizable (GtkSheet
*sheet
, gboolean resizable
)
2029 g_return_if_fail (sheet
!= NULL
);
2030 g_return_if_fail (GTK_IS_SHEET (sheet
));
2032 sheet
->rows_resizable
= resizable
;
2036 gtk_sheet_rows_resizable (GtkSheet
*sheet
)
2038 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2039 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
2041 return sheet
->rows_resizable
;
2045 gtk_sheet_column_set_visibility(GtkSheet
*sheet
, gint column
, gboolean visible
)
2047 g_return_if_fail (sheet
!= NULL
);
2048 g_return_if_fail (GTK_IS_SHEET (sheet
));
2050 if(column
< 0 || column
> sheet
->maxcol
) return;
2051 if(sheet
->column
[column
].is_visible
== visible
) return;
2053 sheet
->column
[column
].is_visible
= visible
;
2055 gtk_sheet_recalc_left_xpixels(sheet
, column
);
2057 if(!GTK_SHEET_IS_FROZEN(sheet
) &&
2058 gtk_sheet_cell_isvisible(sheet
, MIN_VISIBLE_ROW(sheet
), column
)){
2059 gtk_sheet_range_draw(sheet
, NULL
);
2060 size_allocate_column_title_buttons(sheet
);
2065 gtk_sheet_row_set_visibility(GtkSheet
*sheet
, gint row
, gboolean visible
)
2067 g_return_if_fail (sheet
!= NULL
);
2068 g_return_if_fail (GTK_IS_SHEET (sheet
));
2070 if(row
< 0 || row
> sheet
->maxrow
) return;
2071 if(sheet
->row
[row
].is_visible
== visible
) return;
2073 sheet
->row
[row
].is_visible
= visible
;
2075 gtk_sheet_recalc_top_ypixels(sheet
, row
);
2077 if(!GTK_SHEET_IS_FROZEN(sheet
) &&
2078 gtk_sheet_cell_isvisible(sheet
, row
, MIN_VISIBLE_COLUMN(sheet
))){
2079 gtk_sheet_range_draw(sheet
, NULL
);
2080 size_allocate_row_title_buttons(sheet
);
2085 gtk_sheet_select_row (GtkSheet
* sheet
,
2088 g_return_if_fail (sheet
!= NULL
);
2089 g_return_if_fail (GTK_IS_SHEET (sheet
));
2091 if (row
< 0 || row
> sheet
->maxrow
)
2094 if(sheet
->state
!= GTK_SHEET_NORMAL
)
2095 gtk_sheet_real_unselect_range(sheet
, NULL
);
2098 gboolean veto
= TRUE
;
2099 veto
= gtk_sheet_deactivate_cell(sheet
);
2103 sheet
->state
=GTK_SHEET_ROW_SELECTED
;
2104 sheet
->range
.row0
=row
;
2105 sheet
->range
.col0
=0;
2106 sheet
->range
.rowi
=row
;
2107 sheet
->range
.coli
=sheet
->maxcol
;
2108 sheet
->active_cell
.row
=row
;
2109 sheet
->active_cell
.col
=0;
2111 gtk_signal_emit (GTK_OBJECT (sheet
), sheet_signals
[SELECT_ROW
], row
);
2112 gtk_sheet_real_select_range(sheet
, NULL
);
2118 gtk_sheet_select_column (GtkSheet
* sheet
,
2122 g_return_if_fail (sheet
!= NULL
);
2123 g_return_if_fail (GTK_IS_SHEET (sheet
));
2125 if (column
< 0 || column
> sheet
->maxcol
)
2128 if(sheet
->state
!= GTK_SHEET_NORMAL
)
2129 gtk_sheet_real_unselect_range(sheet
, NULL
);
2132 gboolean veto
= TRUE
;
2133 veto
= gtk_sheet_deactivate_cell(sheet
);
2137 sheet
->state
=GTK_SHEET_COLUMN_SELECTED
;
2138 sheet
->range
.row0
=0;
2139 sheet
->range
.col0
=column
;
2140 sheet
->range
.rowi
=sheet
->maxrow
;
2141 sheet
->range
.coli
=column
;
2142 sheet
->active_cell
.row
=0;
2143 sheet
->active_cell
.col
=column
;
2145 gtk_signal_emit (GTK_OBJECT (sheet
), sheet_signals
[SELECT_COLUMN
], column
);
2146 gtk_sheet_real_select_range(sheet
, NULL
);
2151 gtk_sheet_clip_range (GtkSheet
*sheet
, const GtkSheetRange
*range
)
2154 g_return_if_fail (sheet
!= NULL
);
2155 g_return_if_fail (GTK_IS_SHEET (sheet
));
2157 if(GTK_SHEET_IN_CLIP(sheet
)) return;
2159 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_CLIP
);
2162 sheet
->clip_range
= sheet
->range
;
2164 sheet
->clip_range
=*range
;
2167 sheet
->clip_timer
=gtk_timeout_add(TIMEOUT_FLASH
, gtk_sheet_flash
, sheet
);
2169 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CLIP_RANGE
],
2170 &sheet
->clip_range
);
2175 gtk_sheet_unclip_range(GtkSheet
*sheet
)
2178 g_return_if_fail (sheet
!= NULL
);
2179 g_return_if_fail (GTK_IS_SHEET (sheet
));
2181 if(!GTK_SHEET_IN_CLIP(sheet
)) return;
2183 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_CLIP
);
2184 gtk_timeout_remove(sheet
->clip_timer
);
2185 gtk_sheet_range_draw(sheet
, &sheet
->clip_range
);
2187 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
2188 gtk_sheet_range_draw(sheet
, &sheet
->range
);
2192 gtk_sheet_in_clip (GtkSheet
*sheet
)
2194 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2195 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
2197 return GTK_SHEET_IN_CLIP(sheet
);
2201 gtk_sheet_flash(gpointer data
)
2204 gint x
,y
,width
,height
;
2205 GdkRectangle clip_area
;
2207 sheet
=GTK_SHEET(data
);
2209 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return TRUE
;
2210 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return TRUE
;
2211 if(!gtk_sheet_range_isvisible(sheet
, sheet
->clip_range
)) return TRUE
;
2212 if(GTK_SHEET_IN_XDRAG(sheet
)) return TRUE
;
2213 if(GTK_SHEET_IN_YDRAG(sheet
)) return TRUE
;
2215 GDK_THREADS_ENTER();
2217 x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.col0
)+1;
2218 y
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.row0
)+1;
2219 width
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.coli
)-x
+
2220 sheet
->column
[sheet
->clip_range
.coli
].width
-1;
2221 height
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.rowi
)-y
+
2222 sheet
->row
[sheet
->clip_range
.rowi
].height
-1;
2224 clip_area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
2225 clip_area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
2226 clip_area
.width
=sheet
->sheet_window_width
;
2227 clip_area
.height
=sheet
->sheet_window_height
;
2233 if(width
>clip_area
.width
) width
=clip_area
.width
+10;
2238 if(height
>clip_area
.height
) height
=clip_area
.height
+10;
2240 gdk_draw_pixmap(sheet
->sheet_window
,
2241 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2247 gdk_draw_pixmap(sheet
->sheet_window
,
2248 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2254 gdk_draw_pixmap(sheet
->sheet_window
,
2255 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2261 gdk_draw_pixmap(sheet
->sheet_window
,
2262 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
2269 sheet
->interval
=sheet
->interval
+1;
2270 if(sheet
->interval
==TIME_INTERVAL
) sheet
->interval
=0;
2272 gdk_gc_set_dashes(sheet
->xor_gc
, sheet
->interval
, (gint8
*)"\4\4", 2);
2273 gtk_sheet_draw_flashing_range(sheet
,sheet
->clip_range
);
2274 gdk_gc_set_dashes(sheet
->xor_gc
, 0, (gint8
*)"\4\4", 2);
2276 GDK_THREADS_LEAVE();
2283 gtk_sheet_draw_flashing_range(GtkSheet
*sheet
, GtkSheetRange range
)
2285 GdkRectangle clip_area
;
2286 gint x
,y
,width
,height
;
2288 if(!gtk_sheet_range_isvisible(sheet
, sheet
->clip_range
)) return;
2290 clip_area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
2291 clip_area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
2292 clip_area
.width
=sheet
->sheet_window_width
;
2293 clip_area
.height
=sheet
->sheet_window_height
;
2295 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &clip_area
);
2297 x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.col0
)+1;
2298 y
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.row0
)+1;
2299 width
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->clip_range
.coli
)-x
+
2300 sheet
->column
[sheet
->clip_range
.coli
].width
-1;
2301 height
=ROW_TOP_YPIXEL(sheet
,sheet
->clip_range
.rowi
)-y
+
2302 sheet
->row
[sheet
->clip_range
.rowi
].height
-1;
2308 if(width
>clip_area
.width
) width
=clip_area
.width
+10;
2313 if(height
>clip_area
.height
) height
=clip_area
.height
+10;
2315 gdk_gc_set_line_attributes(sheet
->xor_gc
, 1, 1, 0 ,0 );
2317 gdk_draw_rectangle(sheet
->sheet_window
, sheet
->xor_gc
, FALSE
,
2321 gdk_gc_set_line_attributes (sheet
->xor_gc
, 1, 0, 0, 0);
2323 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
2328 gtk_sheet_range_isvisible (GtkSheet
* sheet
,
2329 GtkSheetRange range
)
2331 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
2333 if (range
.row0
< 0 || range
.row0
> sheet
->maxrow
)
2336 if (range
.rowi
< 0 || range
.rowi
> sheet
->maxrow
)
2339 if (range
.col0
< 0 || range
.col0
> sheet
->maxcol
)
2342 if (range
.coli
< 0 || range
.coli
> sheet
->maxcol
)
2345 if (range
.rowi
< MIN_VISIBLE_ROW (sheet
))
2348 if (range
.row0
> MAX_VISIBLE_ROW (sheet
))
2351 if (range
.coli
< MIN_VISIBLE_COLUMN (sheet
))
2354 if (range
.col0
> MAX_VISIBLE_COLUMN (sheet
))
2361 gtk_sheet_cell_isvisible (GtkSheet
* sheet
,
2362 gint row
, gint column
)
2364 GtkSheetRange range
;
2367 range
.col0
= column
;
2369 range
.coli
= column
;
2371 return gtk_sheet_range_isvisible(sheet
, range
);
2375 gtk_sheet_get_visible_range(GtkSheet
*sheet
, GtkSheetRange
*range
)
2378 g_return_if_fail (sheet
!= NULL
);
2379 g_return_if_fail (GTK_IS_SHEET (sheet
)) ;
2380 g_return_if_fail (range
!= NULL
);
2382 range
->row0
= MIN_VISIBLE_ROW(sheet
);
2383 range
->col0
= MIN_VISIBLE_COLUMN(sheet
);
2384 range
->rowi
= MAX_VISIBLE_ROW(sheet
);
2385 range
->coli
= MAX_VISIBLE_COLUMN(sheet
);
2390 gtk_sheet_get_vadjustment (GtkSheet
* sheet
)
2392 g_return_val_if_fail (sheet
!= NULL
, NULL
);
2393 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
2395 return sheet
->vadjustment
;
2399 gtk_sheet_get_hadjustment (GtkSheet
* sheet
)
2401 g_return_val_if_fail (sheet
!= NULL
, NULL
);
2402 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
2404 return sheet
->hadjustment
;
2408 gtk_sheet_set_vadjustment (GtkSheet
*sheet
,
2409 GtkAdjustment
*adjustment
)
2411 GtkAdjustment
*old_adjustment
;
2413 g_return_if_fail (sheet
!= NULL
);
2414 g_return_if_fail (GTK_IS_SHEET (sheet
));
2416 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment
));
2418 if (sheet
->vadjustment
== adjustment
)
2421 old_adjustment
= sheet
->vadjustment
;
2423 if (sheet
->vadjustment
)
2425 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->vadjustment
), sheet
);
2426 gtk_object_unref (GTK_OBJECT (sheet
->vadjustment
));
2429 sheet
->vadjustment
= adjustment
;
2431 if (sheet
->vadjustment
)
2433 gtk_object_ref (GTK_OBJECT (sheet
->vadjustment
));
2434 gtk_object_sink (GTK_OBJECT (sheet
->vadjustment
));
2436 gtk_signal_connect (GTK_OBJECT (sheet
->vadjustment
), "changed",
2437 (GtkSignalFunc
) vadjustment_changed
,
2439 gtk_signal_connect (GTK_OBJECT (sheet
->vadjustment
), "value_changed",
2440 (GtkSignalFunc
) vadjustment_value_changed
,
2444 if (!sheet
->vadjustment
|| !old_adjustment
)
2446 gtk_widget_queue_resize (GTK_WIDGET (sheet
));
2450 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
2454 gtk_sheet_set_hadjustment (GtkSheet
*sheet
,
2455 GtkAdjustment
*adjustment
)
2457 GtkAdjustment
*old_adjustment
;
2459 g_return_if_fail (sheet
!= NULL
);
2460 g_return_if_fail (GTK_IS_SHEET (sheet
));
2462 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment
));
2464 if (sheet
->hadjustment
== adjustment
)
2467 old_adjustment
= sheet
->hadjustment
;
2469 if (sheet
->hadjustment
)
2471 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->hadjustment
), sheet
);
2472 gtk_object_unref (GTK_OBJECT (sheet
->hadjustment
));
2475 sheet
->hadjustment
= adjustment
;
2477 if (sheet
->hadjustment
)
2479 gtk_object_ref (GTK_OBJECT (sheet
->hadjustment
));
2480 gtk_object_sink (GTK_OBJECT (sheet
->hadjustment
));
2482 gtk_signal_connect (GTK_OBJECT (sheet
->hadjustment
), "changed",
2483 (GtkSignalFunc
) hadjustment_changed
,
2485 gtk_signal_connect (GTK_OBJECT (sheet
->hadjustment
), "value_changed",
2486 (GtkSignalFunc
) hadjustment_value_changed
,
2490 if (!sheet
->hadjustment
|| !old_adjustment
)
2492 gtk_widget_queue_resize (GTK_WIDGET (sheet
));
2496 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
2500 gtk_sheet_set_scroll_adjustments (GtkSheet
*sheet
,
2501 GtkAdjustment
*hadjustment
,
2502 GtkAdjustment
*vadjustment
)
2504 if(sheet
->hadjustment
!= hadjustment
)
2505 gtk_sheet_set_hadjustment (sheet
, hadjustment
);
2506 if(sheet
->vadjustment
!= vadjustment
)
2507 gtk_sheet_set_vadjustment (sheet
, vadjustment
);
2511 gtk_sheet_finalize (GObject
* object
)
2515 g_return_if_fail (object
!= NULL
);
2516 g_return_if_fail (GTK_IS_SHEET (object
));
2518 sheet
= GTK_SHEET (object
);
2520 /* get rid of all the cells */
2521 gtk_sheet_range_clear (sheet
, NULL
);
2522 gtk_sheet_range_delete(sheet
, NULL
);
2524 gtk_sheet_delete_rows (sheet
, 0, sheet
->maxrow
+ 1);
2525 gtk_sheet_delete_columns (sheet
, 0, sheet
->maxcol
+ 1);
2527 DeleteRow (sheet
, 0, sheet
->maxrow
+ 1);
2528 DeleteColumn (sheet
, 0, sheet
->maxcol
+ 1);
2532 g_free(sheet
->column
);
2533 sheet
->column
= NULL
;
2534 g_free(sheet
->data
);
2538 g_free(sheet
->name
);
2542 if (G_OBJECT_CLASS (parent_class
)->finalize
)
2543 (*G_OBJECT_CLASS (parent_class
)->finalize
) (object
);
2547 gtk_sheet_destroy (GtkObject
* object
)
2552 g_return_if_fail (object
!= NULL
);
2553 g_return_if_fail (GTK_IS_SHEET (object
));
2555 sheet
= GTK_SHEET (object
);
2557 /* destroy the entry */
2558 if(sheet
->sheet_entry
&& GTK_IS_WIDGET(sheet
->sheet_entry
)){
2559 gtk_widget_destroy (sheet
->sheet_entry
);
2560 sheet
->sheet_entry
= NULL
;
2563 /* destroy the global selection button */
2564 if(sheet
->button
&& GTK_IS_WIDGET(sheet
->button
)){
2565 gtk_widget_destroy (sheet
->button
);
2566 sheet
->button
= NULL
;
2570 gtk_timeout_remove(sheet
->timer
);
2574 if(sheet
->clip_timer
){
2575 gtk_timeout_remove(sheet
->clip_timer
);
2576 sheet
->clip_timer
= 0;
2579 /* unref adjustments */
2580 if (sheet
->hadjustment
)
2582 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->hadjustment
), sheet
);
2583 gtk_object_unref (GTK_OBJECT (sheet
->hadjustment
));
2584 sheet
->hadjustment
= NULL
;
2586 if (sheet
->vadjustment
)
2588 gtk_signal_disconnect_by_data (GTK_OBJECT (sheet
->vadjustment
), sheet
);
2589 gtk_object_unref (GTK_OBJECT (sheet
->vadjustment
));
2590 sheet
->vadjustment
= NULL
;
2593 children
= sheet
->children
;
2595 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
2596 if(child
&& child
->widget
)
2597 gtk_sheet_remove(GTK_CONTAINER(sheet
), child
->widget
);
2598 children
= sheet
->children
;
2600 sheet
->children
= NULL
;
2602 if (GTK_OBJECT_CLASS (parent_class
)->destroy
)
2603 (*GTK_OBJECT_CLASS (parent_class
)->destroy
) (object
);
2607 gtk_sheet_style_set (GtkWidget
*widget
,
2608 GtkStyle
*previous_style
)
2612 g_return_if_fail (widget
!= NULL
);
2613 g_return_if_fail (GTK_IS_SHEET (widget
));
2615 if (GTK_WIDGET_CLASS (parent_class
)->style_set
)
2616 (*GTK_WIDGET_CLASS (parent_class
)->style_set
) (widget
, previous_style
);
2618 sheet
= GTK_SHEET (widget
);
2620 if(GTK_WIDGET_REALIZED(widget
))
2622 gtk_style_set_background (widget
->style
, widget
->window
, widget
->state
);
2628 gtk_sheet_realize (GtkWidget
* widget
)
2631 GdkWindowAttr attributes
;
2632 gint attributes_mask
;
2633 GdkGCValues values
, auxvalues
;
2634 GdkColormap
*colormap
;
2636 GtkSheetChild
*child
;
2639 g_return_if_fail (widget
!= NULL
);
2640 g_return_if_fail (GTK_IS_SHEET (widget
));
2642 sheet
= GTK_SHEET (widget
);
2644 GTK_WIDGET_SET_FLAGS (widget
, GTK_REALIZED
);
2646 attributes
.window_type
= GDK_WINDOW_CHILD
;
2647 attributes
.x
= widget
->allocation
.x
;
2648 attributes
.y
= widget
->allocation
.y
;
2649 attributes
.width
= widget
->allocation
.width
;
2650 attributes
.height
= widget
->allocation
.height
;
2651 attributes
.wclass
= GDK_INPUT_OUTPUT
;
2653 attributes
.visual
= gtk_widget_get_visual (widget
);
2654 attributes
.colormap
= gtk_widget_get_colormap (widget
);
2656 attributes
.event_mask
= gtk_widget_get_events (widget
);
2657 attributes
.event_mask
|= (GDK_EXPOSURE_MASK
|
2658 GDK_BUTTON_PRESS_MASK
|
2659 GDK_BUTTON_RELEASE_MASK
|
2660 GDK_KEY_PRESS_MASK
|
2661 GDK_POINTER_MOTION_MASK
|
2662 GDK_POINTER_MOTION_HINT_MASK
);
2663 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
|
2666 attributes
.cursor
= gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
2669 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
, attributes_mask
);
2671 gdk_window_set_user_data (widget
->window
, sheet
);
2673 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
2675 gtk_style_set_background (widget
->style
, widget
->window
, GTK_STATE_NORMAL
);
2678 if(sheet
->row_titles_visible
)
2679 attributes
.x
= sheet
->row_title_area
.width
;
2681 attributes
.width
= sheet
->column_title_area
.width
;
2682 attributes
.height
= sheet
->column_title_area
.height
;
2684 /* column-title window */
2685 sheet
->column_title_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2686 gdk_window_set_user_data (sheet
->column_title_window
, sheet
);
2687 gtk_style_set_background (widget
->style
, sheet
->column_title_window
, GTK_STATE_NORMAL
);
2691 if(sheet
->column_titles_visible
)
2692 attributes
.y
= sheet
->column_title_area
.height
;
2693 attributes
.width
= sheet
->row_title_area
.width
;
2694 attributes
.height
= sheet
->row_title_area
.height
;
2696 /* row-title window */
2697 sheet
->row_title_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2698 gdk_window_set_user_data (sheet
->row_title_window
, sheet
);
2699 gtk_style_set_background (widget
->style
, sheet
->row_title_window
, GTK_STATE_NORMAL
);
2702 attributes
.cursor
= gdk_cursor_new(GDK_PLUS
);
2706 attributes
.width
= sheet
->sheet_window_width
,
2707 attributes
.height
= sheet
->sheet_window_height
;
2709 sheet
->sheet_window
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
2710 gdk_window_set_user_data (sheet
->sheet_window
, sheet
);
2712 gdk_window_set_background (sheet
->sheet_window
, &widget
->style
->white
);
2713 gdk_window_show (sheet
->sheet_window
);
2715 /* backing_pixmap */
2716 gtk_sheet_make_backing_pixmap(sheet
, 0, 0);
2720 gdk_gc_unref(sheet
->fg_gc
);
2722 gdk_gc_unref(sheet
->bg_gc
);
2723 sheet
->fg_gc
= gdk_gc_new (widget
->window
);
2724 sheet
->bg_gc
= gdk_gc_new (widget
->window
);
2726 colormap
= gtk_widget_get_colormap(widget
);
2728 gdk_color_white(colormap
, &widget
->style
->white
);
2729 gdk_color_black(colormap
, &widget
->style
->black
);
2731 gdk_gc_get_values(sheet
->fg_gc
, &auxvalues
);
2733 values
.foreground
= widget
->style
->white
;
2734 values
.function
= GDK_INVERT
;
2735 values
.subwindow_mode
= GDK_INCLUDE_INFERIORS
;
2737 gdk_gc_unref(sheet
->xor_gc
);
2738 sheet
->xor_gc
= gdk_gc_new_with_values (widget
->window
,
2744 if(sheet
->sheet_entry
->parent
){
2745 gtk_widget_ref(sheet
->sheet_entry
);
2746 gtk_widget_unparent(sheet
->sheet_entry
);
2748 gtk_widget_set_parent_window (sheet
->sheet_entry
, sheet
->sheet_window
);
2749 gtk_widget_set_parent(sheet
->sheet_entry
, GTK_WIDGET(sheet
));
2751 if(sheet
->button
&& sheet
->button
->parent
){
2752 gtk_widget_ref(sheet
->button
);
2753 gtk_widget_unparent(sheet
->button
);
2755 gtk_widget_set_parent_window(sheet
->button
, sheet
->sheet_window
);
2756 gtk_widget_set_parent(sheet
->button
, GTK_WIDGET(sheet
));
2759 gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col);
2761 if(!sheet
->cursor_drag
)
2762 sheet
->cursor_drag
= gdk_cursor_new(GDK_PLUS
);
2764 if(sheet
->column_titles_visible
)
2765 gdk_window_show(sheet
->column_title_window
);
2766 if(sheet
->row_titles_visible
)
2767 gdk_window_show(sheet
->row_title_window
);
2769 size_allocate_row_title_buttons(sheet
);
2770 size_allocate_column_title_buttons(sheet
);
2772 name
= g_strdup(sheet
->name
);
2773 gtk_sheet_set_title(sheet
, name
);
2777 children
= sheet
->children
;
2780 child
= children
->data
;
2781 children
= g_list_next(children
);
2783 gtk_sheet_realize_child(sheet
, child
);
2788 create_global_button(GtkSheet
*sheet
)
2790 sheet
->button
= gtk_button_new_with_label(" ");
2792 gtk_signal_connect (GTK_OBJECT (sheet
->button
),
2794 (GtkSignalFunc
) global_button_clicked
,
2799 size_allocate_global_button(GtkSheet
*sheet
)
2801 GtkAllocation allocation
;
2803 if(!sheet
->column_titles_visible
) return;
2804 if(!sheet
->row_titles_visible
) return;
2806 gtk_widget_size_request(sheet
->button
, NULL
);
2810 allocation
.width
=sheet
->row_title_area
.width
;
2811 allocation
.height
=sheet
->column_title_area
.height
;
2813 gtk_widget_size_allocate(sheet
->button
, &allocation
);
2814 gtk_widget_show(sheet
->button
);
2818 global_button_clicked(GtkWidget
*widget
, gpointer data
)
2822 gtk_sheet_click_cell(GTK_SHEET(data
), -1, -1, &veto
);
2823 gtk_widget_grab_focus(GTK_WIDGET(data
));
2828 gtk_sheet_unrealize (GtkWidget
* widget
)
2832 g_return_if_fail (widget
!= NULL
);
2833 g_return_if_fail (GTK_IS_SHEET (widget
));
2835 sheet
= GTK_SHEET (widget
);
2837 gdk_cursor_destroy (sheet
->cursor_drag
);
2839 gdk_gc_destroy (sheet
->xor_gc
);
2840 gdk_gc_destroy (sheet
->fg_gc
);
2841 gdk_gc_destroy (sheet
->bg_gc
);
2843 gdk_window_destroy (sheet
->sheet_window
);
2844 gdk_window_destroy (sheet
->column_title_window
);
2845 gdk_window_destroy (sheet
->row_title_window
);
2848 g_object_unref (sheet
->pixmap
);
2849 sheet
->pixmap
= NULL
;
2852 sheet
->column_title_window
=NULL
;
2853 sheet
->sheet_window
= NULL
;
2854 sheet
->cursor_drag
= NULL
;
2855 sheet
->xor_gc
= NULL
;
2856 sheet
->fg_gc
= NULL
;
2857 sheet
->bg_gc
= NULL
;
2859 if (GTK_WIDGET_CLASS (parent_class
)->unrealize
)
2860 (* GTK_WIDGET_CLASS (parent_class
)->unrealize
) (widget
);
2864 gtk_sheet_map (GtkWidget
* widget
)
2867 GtkSheetChild
*child
;
2870 g_return_if_fail (widget
!= NULL
);
2871 g_return_if_fail (GTK_IS_SHEET (widget
));
2873 sheet
= GTK_SHEET (widget
);
2875 if (!GTK_WIDGET_MAPPED (widget
))
2877 GTK_WIDGET_SET_FLAGS (widget
, GTK_MAPPED
);
2879 if(!sheet
->cursor_drag
) sheet
->cursor_drag
=gdk_cursor_new(GDK_PLUS
);
2881 gdk_window_show (widget
->window
);
2883 gdk_window_show (sheet
->sheet_window
);
2885 if(sheet
->column_titles_visible
){
2886 gdk_window_show (sheet
->column_title_window
);
2888 if(sheet
->row_titles_visible
){
2889 gdk_window_show (sheet
->row_title_window
);
2892 if(!GTK_WIDGET_MAPPED (sheet
->sheet_entry
)){
2893 gtk_widget_show (sheet
->sheet_entry
);
2894 gtk_widget_map (sheet
->sheet_entry
);
2897 if (GTK_WIDGET_VISIBLE (sheet
->button
) &&
2898 !GTK_WIDGET_MAPPED (sheet
->button
)){
2899 gtk_widget_show(sheet
->button
);
2900 gtk_widget_map (sheet
->button
);
2903 if(GTK_BIN(sheet
->button
)->child
)
2904 if (GTK_WIDGET_VISIBLE (GTK_BIN(sheet
->button
)->child
) &&
2905 !GTK_WIDGET_MAPPED (GTK_BIN(sheet
->button
)->child
))
2906 gtk_widget_map (GTK_BIN(sheet
->button
)->child
);
2908 gtk_sheet_range_draw(sheet
, NULL
);
2909 gtk_sheet_activate_cell(sheet
,
2910 sheet
->active_cell
.row
,
2911 sheet
->active_cell
.col
);
2913 children
= sheet
->children
;
2916 child
= children
->data
;
2917 children
= g_list_next(children
);
2919 if (GTK_WIDGET_VISIBLE (child
->widget
) &&
2920 !GTK_WIDGET_MAPPED (child
->widget
)){
2921 gtk_widget_map (child
->widget
);
2922 gtk_sheet_position_child(sheet
, child
);
2930 gtk_sheet_unmap (GtkWidget
* widget
)
2933 GtkSheetChild
*child
;
2936 g_return_if_fail (widget
!= NULL
);
2937 g_return_if_fail (GTK_IS_SHEET (widget
));
2939 sheet
= GTK_SHEET (widget
);
2941 if (GTK_WIDGET_MAPPED (widget
))
2943 GTK_WIDGET_UNSET_FLAGS (widget
, GTK_MAPPED
);
2945 gdk_window_hide (sheet
->sheet_window
);
2946 if(sheet
->column_titles_visible
)
2947 gdk_window_hide (sheet
->column_title_window
);
2948 if(sheet
->row_titles_visible
)
2949 gdk_window_hide (sheet
->row_title_window
);
2950 gdk_window_hide (widget
->window
);
2952 if (GTK_WIDGET_MAPPED (sheet
->sheet_entry
))
2953 gtk_widget_unmap (sheet
->sheet_entry
);
2955 if (GTK_WIDGET_MAPPED (sheet
->button
))
2956 gtk_widget_unmap (sheet
->button
);
2958 children
= sheet
->children
;
2961 child
= children
->data
;
2962 children
= g_list_next(children
);
2964 if (GTK_WIDGET_VISIBLE (child
->widget
) &&
2965 GTK_WIDGET_MAPPED (child
->widget
))
2967 gtk_widget_unmap (child
->widget
);
2976 gtk_sheet_cell_draw_default (GtkSheet
*sheet
, gint row
, gint col
)
2979 GdkGC
*fg_gc
, *bg_gc
;
2980 GtkSheetCellAttr attributes
;
2983 g_return_if_fail (sheet
!= NULL
);
2985 /* bail now if we arn't drawable yet */
2986 if (!GTK_WIDGET_DRAWABLE (sheet
)) return;
2988 if (row
< 0 || row
> sheet
->maxrow
) return;
2989 if (col
< 0 || col
> sheet
->maxcol
) return;
2990 if (!sheet
->column
[col
].is_visible
) return;
2991 if (!sheet
->row
[row
].is_visible
) return;
2993 widget
= GTK_WIDGET (sheet
);
2995 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
2997 /* select GC for background rectangle */
2998 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.foreground
);
2999 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3001 fg_gc
= sheet
->fg_gc
;
3002 bg_gc
= sheet
->bg_gc
;
3004 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3005 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3006 area
.width
=sheet
->column
[col
].width
;
3007 area
.height
=sheet
->row
[row
].height
;
3009 gdk_draw_rectangle (sheet
->pixmap
,
3017 gdk_gc_set_line_attributes (sheet
->fg_gc
, 1, 0, 0, 0);
3019 if(sheet
->show_grid
){
3020 gdk_gc_set_foreground (sheet
->bg_gc
, &sheet
->grid_color
);
3022 gdk_draw_rectangle (sheet
->pixmap
,
3026 area
.width
, area
.height
);
3031 gtk_sheet_cell_draw_border (GtkSheet
*sheet
, gint row
, gint col
, gint mask
)
3034 GdkGC
*fg_gc
, *bg_gc
;
3035 GtkSheetCellAttr attributes
;
3039 g_return_if_fail (sheet
!= NULL
);
3041 /* bail now if we arn't drawable yet */
3042 if (!GTK_WIDGET_DRAWABLE (sheet
)) return;
3044 if (row
< 0 || row
> sheet
->maxrow
) return;
3045 if (col
< 0 || col
> sheet
->maxcol
) return;
3046 if (!sheet
->column
[col
].is_visible
) return;
3047 if (!sheet
->row
[row
].is_visible
) return;
3049 widget
= GTK_WIDGET (sheet
);
3051 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3053 /* select GC for background rectangle */
3054 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.border
.color
);
3055 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3057 fg_gc
= sheet
->fg_gc
;
3058 bg_gc
= sheet
->bg_gc
;
3060 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3061 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3062 area
.width
=sheet
->column
[col
].width
;
3063 area
.height
=sheet
->row
[row
].height
;
3065 width
= attributes
.border
.width
;
3066 gdk_gc_set_line_attributes(sheet
->fg_gc
, attributes
.border
.width
,
3067 attributes
.border
.line_style
,
3068 attributes
.border
.cap_style
,
3069 attributes
.border
.join_style
);
3072 if(attributes
.border
.mask
& GTK_SHEET_LEFT_BORDER
& mask
)
3073 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3074 area
.x
, area
.y
-width
/2,
3075 area
.x
, area
.y
+area
.height
+width
/2+1);
3077 if(attributes
.border
.mask
& GTK_SHEET_RIGHT_BORDER
& mask
)
3078 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3079 area
.x
+area
.width
, area
.y
-width
/2,
3081 area
.y
+area
.height
+width
/2+1);
3083 if(attributes
.border
.mask
& GTK_SHEET_TOP_BORDER
& mask
)
3084 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3085 area
.x
-width
/2,area
.y
,
3086 area
.x
+area
.width
+width
/2+1,
3089 if(attributes
.border
.mask
& GTK_SHEET_BOTTOM_BORDER
& mask
)
3090 gdk_draw_line(sheet
->pixmap
, sheet
->fg_gc
,
3091 area
.x
-width
/2, area
.y
+area
.height
,
3092 area
.x
+area
.width
+width
/2+1,
3093 area
.y
+area
.height
);
3100 gtk_sheet_cell_draw_label (GtkSheet
*sheet
, gint row
, gint col
)
3103 GdkRectangle area
, clip_area
;
3105 gint text_width
, text_height
, y
;
3107 gint size
, sizel
, sizer
;
3108 GdkGC
*fg_gc
, *bg_gc
;
3109 GtkSheetCellAttr attributes
;
3110 PangoLayout
*layout
;
3111 PangoRectangle rect
;
3112 PangoRectangle logical_rect
;
3113 PangoLayoutLine
*line
;
3114 PangoFontMetrics
*metrics
;
3115 PangoContext
*context
= gtk_widget_get_pango_context(GTK_WIDGET(sheet
));
3116 gint ascent
, descent
, y_pos
;
3120 g_return_if_fail (sheet
!= NULL
);
3122 /* bail now if we aren't drawable yet */
3123 if (!GTK_WIDGET_DRAWABLE (sheet
))
3126 if (row
> sheet
->maxallocrow
) return;
3127 if (col
> sheet
->maxalloccol
) return;
3128 if (!sheet
->data
[row
]) return;
3129 if (!sheet
->data
[row
][col
]) return;
3130 if (!sheet
->data
[row
][col
]->text
|| strlen(sheet
->data
[row
][col
]->text
)==0)
3133 if (row
< 0 || row
> sheet
->maxrow
) return;
3134 if (col
< 0 || col
> sheet
->maxcol
) return;
3135 if (!sheet
->column
[col
].is_visible
) return;
3136 if (!sheet
->row
[row
].is_visible
) return;
3139 widget
= GTK_WIDGET(sheet
);
3141 label
= sheet
->data
[row
][col
]->text
;
3143 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3145 /* select GC for background rectangle */
3146 gdk_gc_set_foreground (sheet
->fg_gc
, &attributes
.foreground
);
3147 gdk_gc_set_foreground (sheet
->bg_gc
, &attributes
.background
);
3149 fg_gc
= sheet
->fg_gc
;
3150 bg_gc
= sheet
->bg_gc
;
3152 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,col
);
3153 area
.y
=ROW_TOP_YPIXEL(sheet
,row
);
3154 area
.width
=sheet
->column
[col
].width
;
3155 area
.height
=sheet
->row
[row
].height
;
3159 layout
= gtk_widget_create_pango_layout (GTK_WIDGET(sheet
), label
);
3160 pango_layout_set_font_description (layout
, attributes
.font_desc
);
3162 pango_layout_get_pixel_extents (layout
, NULL
, &rect
);
3164 line
= pango_layout_get_lines (layout
)->data
;
3165 pango_layout_line_get_extents (line
, NULL
, &logical_rect
);
3167 metrics
= pango_context_get_metrics(context
,
3168 attributes
.font_desc
,
3169 pango_context_get_language(context
));
3171 ascent
= pango_font_metrics_get_ascent(metrics
) / PANGO_SCALE
;
3172 descent
= pango_font_metrics_get_descent(metrics
) / PANGO_SCALE
;
3174 pango_font_metrics_unref(metrics
);
3176 /* Align primarily for locale's ascent/descent */
3178 logical_rect
.height
/= PANGO_SCALE
;
3179 logical_rect
.y
/= PANGO_SCALE
;
3180 y_pos
= area
.height
- logical_rect
.height
;
3182 if (logical_rect
.height
> area
.height
)
3183 y_pos
= (logical_rect
.height
- area
.height
- 2*CELLOFFSET
) / 2;
3186 else if (y_pos
+ logical_rect
.height
> area
.height
)
3187 y_pos
= area
.height
- logical_rect
.height
;
3189 text_width
= rect
.width
;
3190 text_height
= rect
.height
;
3191 y
= area
.y
+ y_pos
- CELLOFFSET
;
3193 switch(attributes
.justification
){
3194 case GTK_JUSTIFY_RIGHT
:
3197 if(!gtk_sheet_clip_text(sheet
)){
3198 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
3199 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3200 if(size
>=text_width
+CELLOFFSET
) break;
3201 size
+=sheet
->column
[i
].width
;
3202 sheet
->column
[i
].right_text_column
= MAX(col
, sheet
->column
[i
].right_text_column
);
3207 xoffset
+=area
.width
-text_width
- 2 * CELLOFFSET
-
3208 attributes
.border
.width
/2;
3210 case GTK_JUSTIFY_CENTER
:
3213 area
.x
+=area
.width
/2;
3214 if(!gtk_sheet_clip_text(sheet
)){
3215 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
3216 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3217 if(sizer
>=text_width
/2) break;
3218 sizer
+=sheet
->column
[i
].width
;
3219 sheet
->column
[i
].left_text_column
= MIN(col
, sheet
->column
[i
].left_text_column
);
3221 for(i
=col
-1; i
>=MIN_VISIBLE_COLUMN(sheet
); i
--){
3222 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3223 if(sizel
>=text_width
/2) break;
3224 sizel
+=sheet
->column
[i
].width
;
3225 sheet
->column
[i
].right_text_column
= MAX(col
, sheet
->column
[i
].right_text_column
);
3227 size
=MIN(sizel
, sizer
);
3230 xoffset
+= sizel
- text_width
/2 - CELLOFFSET
;
3231 area
.width
=sizel
+sizer
;
3233 case GTK_JUSTIFY_LEFT
:
3236 if(!gtk_sheet_clip_text(sheet
)){
3237 for(i
=col
+1; i
<=MAX_VISIBLE_COLUMN(sheet
); i
++){
3238 if(gtk_sheet_cell_get_text(sheet
, row
, i
)) break;
3239 if(size
>=text_width
+CELLOFFSET
) break;
3240 size
+=sheet
->column
[i
].width
;
3241 sheet
->column
[i
].left_text_column
= MIN(col
, sheet
->column
[i
].left_text_column
);
3245 xoffset
+= attributes
.border
.width
/2;
3249 if(!gtk_sheet_clip_text(sheet
)) clip_area
= area
;
3250 gdk_gc_set_clip_rectangle(fg_gc
, &clip_area
);
3253 gdk_draw_layout (sheet
->pixmap
, fg_gc
,
3254 area
.x
+ xoffset
+ CELLOFFSET
,
3258 gdk_gc_set_clip_rectangle(fg_gc
, NULL
);
3259 g_object_unref(G_OBJECT(layout
));
3261 gdk_draw_pixmap(sheet
->sheet_window
,
3262 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3276 gtk_sheet_range_draw(GtkSheet
*sheet
, const GtkSheetRange
*range
)
3279 GtkSheetRange drawing_range
;
3282 g_return_if_fail(sheet
!= NULL
);
3283 g_return_if_fail(GTK_SHEET(sheet
));
3285 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return;
3286 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3287 if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
))) return;
3291 drawing_range
.row0
=MIN_VISIBLE_ROW(sheet
);
3292 drawing_range
.col0
=MIN_VISIBLE_COLUMN(sheet
);
3293 drawing_range
.rowi
=MAX_VISIBLE_ROW(sheet
);
3294 drawing_range
.coli
=MAX_VISIBLE_COLUMN(sheet
);
3296 gdk_draw_rectangle (sheet->pixmap,
3297 GTK_WIDGET(sheet)->style->white_gc,
3300 sheet->sheet_window_width,sheet->sheet_window_height);
3305 drawing_range
.row0
=MAX(range
->row0
, MIN_VISIBLE_ROW(sheet
));
3306 drawing_range
.col0
=MAX(range
->col0
, MIN_VISIBLE_COLUMN(sheet
));
3307 drawing_range
.rowi
=MIN(range
->rowi
, MAX_VISIBLE_ROW(sheet
));
3308 drawing_range
.coli
=MIN(range
->coli
, MAX_VISIBLE_COLUMN(sheet
));
3311 if(drawing_range
.coli
== sheet
->maxcol
){
3312 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,sheet
->maxcol
)+
3313 sheet
->column
[sheet
->maxcol
].width
+1;
3316 gdk_gc_set_foreground(sheet
->fg_gc
, &sheet
->bg_color
);
3318 gdk_draw_rectangle (sheet
->pixmap
,
3322 sheet
->sheet_window_width
- area
.x
,
3323 sheet
->sheet_window_height
);
3325 gdk_draw_pixmap(sheet
->sheet_window
,
3326 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3332 sheet
->sheet_window_width
- area
.x
,
3333 sheet
->sheet_window_height
);
3335 if(drawing_range
.rowi
== sheet
->maxrow
){
3337 area
.y
=ROW_TOP_YPIXEL(sheet
,sheet
->maxrow
)+sheet
->row
[sheet
->maxrow
].height
+1;
3339 gdk_gc_set_foreground(sheet
->fg_gc
, &sheet
->bg_color
);
3341 gdk_draw_rectangle (sheet
->pixmap
,
3345 sheet
->sheet_window_width
,
3346 sheet
->sheet_window_height
- area
.y
);
3348 gdk_draw_pixmap(sheet
->sheet_window
,
3349 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3355 sheet
->sheet_window_width
,
3356 sheet
->sheet_window_height
- area
.y
);
3359 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3360 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++){
3361 gtk_sheet_cell_draw_default(sheet
, i
, j
);
3364 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3365 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++){
3366 gtk_sheet_cell_draw_border(sheet
, i
-1, j
, GTK_SHEET_BOTTOM_BORDER
);
3367 gtk_sheet_cell_draw_border(sheet
, i
+1, j
, GTK_SHEET_TOP_BORDER
);
3368 gtk_sheet_cell_draw_border(sheet
, i
, j
-1, GTK_SHEET_RIGHT_BORDER
);
3369 gtk_sheet_cell_draw_border(sheet
, i
, j
+1, GTK_SHEET_LEFT_BORDER
);
3370 gtk_sheet_cell_draw_border(sheet
, i
, j
, 15);
3373 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3374 for(j
=drawing_range
.col0
; j
<=drawing_range
.coli
; j
++)
3375 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3376 sheet
->data
[i
] && sheet
->data
[i
][j
])
3377 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3379 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3380 for(j
=sheet
->column
[drawing_range
.col0
].left_text_column
; j
<drawing_range
.col0
; j
++)
3381 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3382 sheet
->data
[i
] && sheet
->data
[i
][j
])
3383 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3385 for(i
=drawing_range
.row0
; i
<=drawing_range
.rowi
; i
++)
3386 for(j
=drawing_range
.coli
+1; j
<=sheet
->column
[drawing_range
.coli
].right_text_column
; j
++)
3387 if(i
<=sheet
->maxallocrow
&& j
<=sheet
->maxalloccol
&&
3388 sheet
->data
[i
] && sheet
->data
[i
][j
])
3389 gtk_sheet_cell_draw_label (sheet
, i
, j
);
3391 gtk_sheet_draw_backing_pixmap(sheet
, drawing_range
);
3393 if(sheet
->state
!= GTK_SHEET_NORMAL
&& gtk_sheet_range_isvisible(sheet
, sheet
->range
))
3394 gtk_sheet_range_draw_selection(sheet
, drawing_range
);
3396 if(sheet
->state
== GTK_STATE_NORMAL
&&
3397 sheet
->active_cell
.row
>= drawing_range
.row0
&&
3398 sheet
->active_cell
.row
<= drawing_range
.rowi
&&
3399 sheet
->active_cell
.col
>= drawing_range
.col0
&&
3400 sheet
->active_cell
.col
<= drawing_range
.coli
)
3401 gtk_sheet_show_active_cell(sheet
);
3406 gtk_sheet_range_draw_selection(GtkSheet
*sheet
, GtkSheetRange range
)
3412 if(range
.col0
> sheet
->range
.coli
|| range
.coli
< sheet
->range
.col0
||
3413 range
.row0
> sheet
->range
.rowi
|| range
.rowi
< sheet
->range
.row0
)
3416 if(!gtk_sheet_range_isvisible(sheet
, range
)) return;
3417 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3421 range
.col0
=MAX(sheet
->range
.col0
, range
.col0
);
3422 range
.coli
=MIN(sheet
->range
.coli
, range
.coli
);
3423 range
.row0
=MAX(sheet
->range
.row0
, range
.row0
);
3424 range
.rowi
=MIN(sheet
->range
.rowi
, range
.rowi
);
3426 range
.col0
=MAX(range
.col0
, MIN_VISIBLE_COLUMN(sheet
));
3427 range
.coli
=MIN(range
.coli
, MAX_VISIBLE_COLUMN(sheet
));
3428 range
.row0
=MAX(range
.row0
, MIN_VISIBLE_ROW(sheet
));
3429 range
.rowi
=MIN(range
.rowi
, MAX_VISIBLE_ROW(sheet
));
3431 for(i
=range
.row0
; i
<=range
.rowi
; i
++){
3432 for(j
=range
.col0
; j
<=range
.coli
; j
++){
3434 if(gtk_sheet_cell_get_state(sheet
, i
, j
)==GTK_STATE_SELECTED
&&
3435 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
3437 row_button_set(sheet
, i
);
3438 column_button_set(sheet
, j
);
3440 area
.x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
3441 area
.y
=ROW_TOP_YPIXEL(sheet
,i
);
3442 area
.width
=sheet
->column
[j
].width
;
3443 area
.height
=sheet
->row
[i
].height
;
3445 if(i
==sheet
->range
.row0
){
3447 area
.height
=area
.height
-2;
3449 if(i
==sheet
->range
.rowi
) area
.height
=area
.height
-3;
3450 if(j
==sheet
->range
.col0
){
3452 area
.width
=area
.width
-2;
3454 if(j
==sheet
->range
.coli
) area
.width
=area
.width
-3;
3456 if(i
!=sheet
->active_cell
.row
|| j
!=sheet
->active_cell
.col
){
3457 gdk_draw_rectangle (sheet
->sheet_window
,
3461 area
.width
,area
.height
);
3468 gtk_sheet_draw_border(sheet
, sheet
->range
);
3473 gtk_sheet_draw_backing_pixmap(GtkSheet
*sheet
, GtkSheetRange range
)
3475 gint x
,y
,width
,height
;
3477 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
3479 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
3480 y
=ROW_TOP_YPIXEL(sheet
, range
.row0
);
3481 width
=COLUMN_LEFT_XPIXEL(sheet
, range
.coli
)-x
+sheet
->column
[range
.coli
].width
;
3482 height
=ROW_TOP_YPIXEL(sheet
, range
.rowi
)-y
+sheet
->row
[range
.rowi
].height
;
3484 if(range
.row0
==sheet
->range
.row0
){
3488 if(range
.rowi
==sheet
->range
.rowi
) height
=height
+5;
3489 if(range
.col0
==sheet
->range
.col0
){
3493 if(range
.coli
==sheet
->range
.coli
) width
=width
+5;
3496 width
=MIN(width
, sheet
->sheet_window_width
-x
);
3497 height
=MIN(height
, sheet
->sheet_window_height
-y
);
3504 x
= (sheet
->row_titles_visible
)
3505 ? MAX(x
, sheet
->row_title_area
.width
) : MAX(x
, 0);
3506 y
= (sheet
->column_titles_visible
)
3507 ? MAX(y
, sheet
->column_title_area
.height
) : MAX(y
, 0);
3509 if(range
.coli
==sheet
->maxcol
) width
=sheet
->sheet_window_width
-x
;
3510 if(range
.rowi
==sheet
->maxrow
) height
=sheet
->sheet_window_height
-y
;
3512 gdk_draw_pixmap(sheet
->sheet_window
,
3513 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
3523 static GtkSheetCell
*
3524 gtk_sheet_cell_new()
3527 cell
= g_new(GtkSheetCell
, 1);
3530 cell
->attributes
= NULL
;
3535 gtk_sheet_set_cell_text(GtkSheet
*sheet
, gint row
, gint col
, const gchar
*text
)
3537 GtkSheetCellAttr attributes
;
3539 g_return_if_fail (sheet
!= NULL
);
3540 g_return_if_fail (GTK_IS_SHEET (sheet
));
3541 if (col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3542 if (col
< 0 || row
< 0) return;
3544 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3545 gtk_sheet_set_cell(sheet
, row
, col
, attributes
.justification
, text
);
3549 gtk_sheet_set_cell(GtkSheet
*sheet
, gint row
, gint col
,
3550 GtkJustification justification
,
3553 GtkSheetCell
**cell
;
3554 GtkSheetRange range
;
3556 GtkSheetCellAttr attributes
;
3558 g_return_if_fail (sheet
!= NULL
);
3559 g_return_if_fail (GTK_IS_SHEET (sheet
));
3560 if (col
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3561 if (col
< 0 || row
< 0) return;
3563 CheckBounds(sheet
, row
, col
);
3565 cell
=&sheet
->data
[row
][col
];
3568 (*cell
) = gtk_sheet_cell_new();
3570 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
3575 attributes
.justification
= justification
;
3576 gtk_sheet_set_cell_attributes(sheet
, row
, col
, attributes
);
3579 g_free((*cell
)->text
);
3580 (*cell
)->text
= NULL
;
3584 (*cell
)->text
=g_strdup(text
);
3586 if(attributes
.is_visible
){
3589 if((*cell
)->text
&& strlen((*cell
)->text
) > 0) {
3590 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), attributes
.font_desc
, (*cell
)->text
);
3595 range
.col0
= sheet
->view
.col0
;
3596 range
.coli
= sheet
->view
.coli
;
3598 if(gtk_sheet_autoresize(sheet
) &&
3599 text_width
> sheet
->column
[col
].width
-2*CELLOFFSET
-attributes
.border
.width
){
3600 gtk_sheet_set_column_width(sheet
, col
, text_width
+2*CELLOFFSET
+attributes
.border
.width
);
3601 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_REDRAW_PENDING
);
3604 if(!GTK_SHEET_IS_FROZEN(sheet
))
3605 gtk_sheet_range_draw(sheet
, &range
);
3607 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CHANGED
], row
, col
);
3613 gtk_sheet_cell_clear (GtkSheet
*sheet
, gint row
, gint column
)
3615 GtkSheetRange range
;
3617 g_return_if_fail (sheet
!= NULL
);
3618 g_return_if_fail (GTK_IS_SHEET (sheet
));
3619 if (column
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3620 if (column
> sheet
->maxalloccol
|| row
> sheet
->maxallocrow
) return;
3621 if (column
< 0 || row
< 0) return;
3625 range
.col0
= sheet
->view
.col0
;
3626 range
.coli
= sheet
->view
.coli
;
3628 gtk_sheet_real_cell_clear(sheet
, row
, column
, FALSE
);
3630 if(!GTK_SHEET_IS_FROZEN(sheet
)){
3631 gtk_sheet_range_draw(sheet
, &range
);
3636 gtk_sheet_cell_delete (GtkSheet
*sheet
, gint row
, gint column
)
3638 GtkSheetRange range
;
3640 g_return_if_fail (sheet
!= NULL
);
3641 g_return_if_fail (GTK_IS_SHEET (sheet
));
3642 if (column
> sheet
->maxcol
|| row
> sheet
->maxrow
) return;
3643 if (column
> sheet
->maxalloccol
|| row
> sheet
->maxallocrow
) return;
3644 if (column
< 0 || row
< 0) return;
3648 range
.col0
= sheet
->view
.col0
;
3649 range
.coli
= sheet
->view
.coli
;
3651 gtk_sheet_real_cell_clear(sheet
, row
, column
, TRUE
);
3653 if(!GTK_SHEET_IS_FROZEN(sheet
)){
3654 gtk_sheet_range_draw(sheet
, &range
);
3659 gtk_sheet_real_cell_clear (GtkSheet
*sheet
, gint row
, gint column
, gboolean
delete)
3664 if(row
> sheet
->maxallocrow
|| column
> sheet
->maxalloccol
) return;
3665 if(!sheet
->data
[row
]) return;
3666 if(!sheet
->data
[row
][column
]) return;
3668 text
= gtk_sheet_cell_get_text(sheet
, row
, column
);
3669 link
= gtk_sheet_get_link(sheet
, row
, column
);
3672 g_free(sheet
->data
[row
][column
]->text
);
3673 sheet
->data
[row
][column
]->text
= NULL
;
3675 if(GTK_IS_OBJECT(sheet
) && G_OBJECT(sheet
)->ref_count
> 0)
3676 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[CLEAR_CELL
], row
, column
);
3678 sheet_head
->CHANGED
= 1;
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 sheet_head
->CHANGED
= 1;
3983 if(sheet
->freeze_count
== 0)
3984 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
3986 sheet
->active_cell
.row
=row
;;
3987 sheet
->active_cell
.col
=col
;
3993 gtk_sheet_deactivate_cell(GtkSheet
*sheet
)
3995 gboolean veto
= TRUE
;
3997 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
3998 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
4000 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return FALSE
;
4001 if(sheet
->state
!= GTK_SHEET_NORMAL
) return FALSE
;
4003 _gtkextra_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[DEACTIVATE
],
4004 sheet
->active_cell
.row
,
4005 sheet
->active_cell
.col
, &veto
);
4007 if(!veto
) return FALSE
;
4009 gtk_signal_disconnect_by_func(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
4010 (GtkSignalFunc
) gtk_sheet_entry_changed
,
4011 GTK_OBJECT(GTK_WIDGET(sheet
)));
4013 gtk_sheet_hide_active_cell(sheet
);
4014 sheet
->active_cell
.row
=-1;
4015 sheet
->active_cell
.col
=-1;
4017 if(GTK_SHEET_REDRAW_PENDING(sheet
)){
4018 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_REDRAW_PENDING
);
4019 gtk_sheet_range_draw(sheet
, NULL
);
4026 gtk_sheet_hide_active_cell(GtkSheet
*sheet
)
4030 GtkJustification justification
;
4031 GtkSheetCellAttr attributes
;
4033 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4035 row
=sheet
->active_cell
.row
;
4036 col
=sheet
->active_cell
.col
;
4038 if(row
< 0 || col
< 0) return;
4040 if(sheet
->freeze_count
== 0)
4041 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IS_FROZEN
);
4043 text
=gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
4045 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
4046 justification
=attributes
.justification
;
4048 if(text
&& strlen(text
)!=0){
4049 gtk_sheet_set_cell(sheet
, row
, col
, justification
, text
);
4050 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[SET_CELL
], row
, col
);
4054 gtk_sheet_cell_clear(sheet
, row
, col
);
4057 row
=sheet
->active_cell
.row
;
4058 col
=sheet
->active_cell
.col
;
4060 column_button_release(sheet
, col
);
4061 row_button_release(sheet
, row
);
4063 gtk_widget_unmap(sheet
->sheet_entry
);
4065 if(row
!= -1 && col
!= -1)
4066 gdk_draw_pixmap(sheet
->sheet_window
,
4067 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4069 COLUMN_LEFT_XPIXEL(sheet
,col
)-1,
4070 ROW_TOP_YPIXEL(sheet
,row
)-1,
4071 COLUMN_LEFT_XPIXEL(sheet
,col
)-1,
4072 ROW_TOP_YPIXEL(sheet
,row
)-1,
4073 sheet
->column
[col
].width
+4,
4074 sheet
->row
[row
].height
+4);
4076 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
4077 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet
), GTK_HAS_FOCUS
);
4078 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4080 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(sheet
->sheet_entry
), GTK_VISIBLE
);
4085 gtk_sheet_activate_cell(GtkSheet
*sheet
, gint row
, gint col
)
4087 gboolean veto
= TRUE
;
4089 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
4090 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
4092 if(row
< 0 || col
< 0) return FALSE
;
4093 if(row
> sheet
->maxrow
|| col
> sheet
->maxcol
) return FALSE
;
4095 /* _gtkextra_signal_emit(GTK_OBJECT(sheet),sheet_signals[ACTIVATE], row, col, &veto);
4096 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return veto;
4099 if(!veto
) return FALSE
;
4100 if(sheet
->state
!= GTK_SHEET_NORMAL
){
4101 sheet
->state
=GTK_SHEET_NORMAL
;
4102 gtk_sheet_real_unselect_range(sheet
, NULL
);
4105 sheet
->range
.row0
=row
;
4106 sheet
->range
.col0
=col
;
4107 sheet
->range
.rowi
=row
;
4108 sheet
->range
.coli
=col
;
4109 sheet
->active_cell
.row
=row
;
4110 sheet
->active_cell
.col
=col
;
4111 sheet
->selection_cell
.row
=row
;
4112 sheet
->selection_cell
.col
=col
;
4113 row_button_set(sheet
, row
);
4114 column_button_set(sheet
, col
);
4116 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
4117 gtk_sheet_show_active_cell(sheet
);
4119 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
4121 (GtkSignalFunc
)gtk_sheet_entry_changed
,
4122 GTK_OBJECT(GTK_WIDGET(sheet
)));
4124 _gtkextra_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[ACTIVATE
], row
, col
, &veto
);
4130 gtk_sheet_show_active_cell(GtkSheet
*sheet
)
4133 GtkEntry
*sheet_entry
;
4134 GtkSheetCellAttr attributes
;
4136 GtkJustification justification
;
4139 g_return_if_fail (sheet
!= NULL
);
4140 g_return_if_fail (GTK_IS_SHEET (sheet
));
4142 row
= sheet
->active_cell
.row
;
4143 col
= sheet
->active_cell
.col
;
4145 /* Don't show the active cell, if there is no active cell: */
4146 if(!(row
>= 0 && col
>= 0)) /* e.g row or coll == -1. */
4149 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4150 if(sheet
->state
!= GTK_SHEET_NORMAL
) return;
4151 if(GTK_SHEET_IN_SELECTION(sheet
)) return;
4153 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet
->sheet_entry
), GTK_VISIBLE
);
4155 sheet_entry
= GTK_ENTRY(gtk_sheet_get_entry(sheet
));
4157 gtk_sheet_get_attributes(sheet
, row
, col
, &attributes
);
4159 justification
= GTK_JUSTIFY_LEFT
;
4161 if(gtk_sheet_justify_entry(sheet
))
4162 justification
= attributes
.justification
;
4164 if(row
<= sheet
->maxallocrow
&& col
<= sheet
->maxalloccol
) {
4165 if(sheet
->data
[row
]) {
4166 if(sheet
->data
[row
][col
]) {
4167 cell
= sheet
->data
[row
][col
];
4169 text
= g_strdup(cell
->text
);
4174 if(!text
) text
= g_strdup("");
4176 gtk_entry_set_visibility(GTK_ENTRY(sheet_entry
), attributes
.is_visible
);
4178 if(gtk_sheet_locked(sheet
) || !attributes
.is_editable
){
4179 gtk_entry_set_editable(GTK_ENTRY(sheet_entry
), FALSE
);
4181 gtk_entry_set_editable(GTK_ENTRY(sheet_entry
), TRUE
);
4185 gtk_entry_set_text(GTK_ENTRY(sheet_entry
), text
);
4188 gtk_sheet_size_allocate_entry(sheet
);
4190 gtk_widget_map(sheet
->sheet_entry
);
4191 gtk_sheet_draw_active_cell(sheet
);
4193 gtk_widget_grab_focus(GTK_WIDGET(sheet_entry
));
4194 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet_entry
), GTK_HAS_FOCUS
);
4195 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(sheet
), GTK_HAS_FOCUS
);
4201 gtk_sheet_draw_active_cell(GtkSheet
*sheet
)
4205 if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet
))) return;
4206 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4208 row
= sheet
->active_cell
.row
;
4209 col
= sheet
->active_cell
.col
;
4211 if(row
<0 || col
<0) return;
4213 if(!gtk_sheet_cell_isvisible(sheet
, row
, col
)) return;
4215 row_button_set(sheet
, row
);
4216 column_button_set(sheet
, col
);
4218 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4219 gtk_sheet_draw_border(sheet
, sheet
->range
);
4225 gtk_sheet_make_backing_pixmap (GtkSheet
*sheet
, guint width
, guint height
)
4227 gint pixmap_width
, pixmap_height
;
4229 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
4231 if(width
== 0 && height
== 0){
4232 width
=sheet
->sheet_window_width
+80;
4233 height
=sheet
->sheet_window_height
+80;
4239 sheet
->pixmap
= gdk_pixmap_new (sheet
->sheet_window
,
4242 if(!GTK_SHEET_IS_FROZEN(sheet
)) gtk_sheet_range_draw(sheet
, NULL
);
4246 /* reallocate if sizes don't match */
4247 gdk_window_get_size (sheet
->pixmap
,
4248 &pixmap_width
, &pixmap_height
);
4249 if ((pixmap_width
!= width
) || (pixmap_height
!= height
))
4251 gdk_pixmap_unref(sheet
->pixmap
); /* replaced by SDB on 7.31.2006 */
4252 /* g_free(sheet->pixmap); */
4253 sheet
->pixmap
= gdk_pixmap_new (sheet
->sheet_window
,
4256 if(!GTK_SHEET_IS_FROZEN(sheet
)) gtk_sheet_range_draw(sheet
, NULL
);
4262 gtk_sheet_new_selection(GtkSheet
*sheet
, GtkSheetRange
*range
)
4264 gint i
,j
, mask1
, mask2
;
4265 gint state
, selected
;
4266 gint x
,y
,width
,height
;
4267 GtkSheetRange new_range
, aux_range
;
4269 g_return_if_fail (sheet
!= NULL
);
4271 if(range
==NULL
) range
=&sheet
->range
;
4275 range
->row0
=MIN(range
->row0
, sheet
->range
.row0
);
4276 range
->rowi
=MAX(range
->rowi
, sheet
->range
.rowi
);
4277 range
->col0
=MIN(range
->col0
, sheet
->range
.col0
);
4278 range
->coli
=MAX(range
->coli
, sheet
->range
.coli
);
4280 range
->row0
=MAX(range
->row0
, MIN_VISIBLE_ROW(sheet
));
4281 range
->rowi
=MIN(range
->rowi
, MAX_VISIBLE_ROW(sheet
));
4282 range
->col0
=MAX(range
->col0
, MIN_VISIBLE_COLUMN(sheet
));
4283 range
->coli
=MIN(range
->coli
, MAX_VISIBLE_COLUMN(sheet
));
4285 aux_range
.row0
=MAX(new_range
.row0
, MIN_VISIBLE_ROW(sheet
));
4286 aux_range
.rowi
=MIN(new_range
.rowi
, MAX_VISIBLE_ROW(sheet
));
4287 aux_range
.col0
=MAX(new_range
.col0
, MIN_VISIBLE_COLUMN(sheet
));
4288 aux_range
.coli
=MIN(new_range
.coli
, MAX_VISIBLE_COLUMN(sheet
));
4290 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4291 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4293 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4294 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4295 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4297 if(state
==GTK_STATE_SELECTED
&& selected
&&
4298 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
&&
4299 (i
==sheet
->range
.row0
|| i
==sheet
->range
.rowi
||
4300 j
==sheet
->range
.col0
|| j
==sheet
->range
.coli
||
4301 i
==new_range
.row0
|| i
==new_range
.rowi
||
4302 j
==new_range
.col0
|| j
==new_range
.coli
)){
4304 mask1
= i
==sheet
->range
.row0
? 1 : 0;
4305 mask1
= i
==sheet
->range
.rowi
? mask1
+2 : mask1
;
4306 mask1
= j
==sheet
->range
.col0
? mask1
+4 : mask1
;
4307 mask1
= j
==sheet
->range
.coli
? mask1
+8 : mask1
;
4309 mask2
= i
==new_range
.row0
? 1 : 0;
4310 mask2
= i
==new_range
.rowi
? mask2
+2 : mask2
;
4311 mask2
= j
==new_range
.col0
? mask2
+4 : mask2
;
4312 mask2
= j
==new_range
.coli
? mask2
+8 : mask2
;
4315 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4316 y
=ROW_TOP_YPIXEL(sheet
, i
);
4317 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4318 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4320 if(i
==sheet
->range
.row0
){
4324 if(i
==sheet
->range
.rowi
) height
=height
+3;
4325 if(j
==sheet
->range
.col0
){
4329 if(j
==sheet
->range
.coli
) width
=width
+3;
4331 gdk_draw_pixmap(sheet
->sheet_window
,
4332 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4341 if(i
!= sheet
->active_cell
.row
|| j
!= sheet
->active_cell
.col
){
4342 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4343 y
=ROW_TOP_YPIXEL(sheet
, i
);
4344 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4345 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4347 if(i
==new_range
.row0
){
4351 if(i
==new_range
.rowi
) height
=height
-3;
4352 if(j
==new_range
.col0
){
4356 if(j
==new_range
.coli
) width
=width
-3;
4358 gdk_draw_rectangle (sheet
->sheet_window
,
4369 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4370 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4372 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4373 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4374 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4376 if(state
==GTK_STATE_SELECTED
&& !selected
&&
4377 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
4379 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4380 y
=ROW_TOP_YPIXEL(sheet
, i
);
4381 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4382 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4384 if(i
==sheet
->range
.row0
){
4388 if(i
==sheet
->range
.rowi
) height
=height
+3;
4389 if(j
==sheet
->range
.col0
){
4393 if(j
==sheet
->range
.coli
) width
=width
+3;
4395 gdk_draw_pixmap(sheet
->sheet_window
,
4396 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4408 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4409 for(j
=range
->col0
; j
<=range
->coli
; j
++){
4411 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4412 selected
=(i
<=new_range
.rowi
&& i
>=new_range
.row0
&&
4413 j
<=new_range
.coli
&& j
>=new_range
.col0
) ? TRUE
: FALSE
;
4415 if(state
!=GTK_STATE_SELECTED
&& selected
&&
4416 sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
&&
4417 (i
!= sheet
->active_cell
.row
|| j
!= sheet
->active_cell
.col
)){
4419 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4420 y
=ROW_TOP_YPIXEL(sheet
, i
);
4421 width
=COLUMN_LEFT_XPIXEL(sheet
, j
)-x
+sheet
->column
[j
].width
;
4422 height
=ROW_TOP_YPIXEL(sheet
, i
)-y
+sheet
->row
[i
].height
;
4424 if(i
==new_range
.row0
){
4428 if(i
==new_range
.rowi
) height
=height
-3;
4429 if(j
==new_range
.col0
){
4433 if(j
==new_range
.coli
) width
=width
-3;
4435 gdk_draw_rectangle (sheet
->sheet_window
,
4446 for(i
=aux_range
.row0
; i
<=aux_range
.rowi
; i
++){
4447 for(j
=aux_range
.col0
; j
<=aux_range
.coli
; j
++){
4449 if(sheet
->column
[j
].is_visible
&& sheet
->row
[i
].is_visible
){
4451 state
=gtk_sheet_cell_get_state(sheet
, i
, j
);
4453 mask1
= i
==sheet
->range
.row0
? 1 : 0;
4454 mask1
= i
==sheet
->range
.rowi
? mask1
+2 : mask1
;
4455 mask1
= j
==sheet
->range
.col0
? mask1
+4 : mask1
;
4456 mask1
= j
==sheet
->range
.coli
? mask1
+8 : mask1
;
4458 mask2
= i
==new_range
.row0
? 1 : 0;
4459 mask2
= i
==new_range
.rowi
? mask2
+2 : mask2
;
4460 mask2
= j
==new_range
.col0
? mask2
+4 : mask2
;
4461 mask2
= j
==new_range
.coli
? mask2
+8 : mask2
;
4462 if(mask2
!=mask1
|| (mask2
==mask1
&& state
!=GTK_STATE_SELECTED
)){
4463 x
=COLUMN_LEFT_XPIXEL(sheet
,j
);
4464 y
=ROW_TOP_YPIXEL(sheet
, i
);
4465 width
=sheet
->column
[j
].width
;
4466 height
=sheet
->row
[i
].height
;
4468 gdk_draw_rectangle (sheet
->sheet_window
,
4476 gdk_draw_rectangle (sheet
->sheet_window
,
4483 gdk_draw_rectangle (sheet
->sheet_window
,
4491 gdk_draw_rectangle (sheet
->sheet_window
,
4508 gtk_sheet_draw_corners(sheet
, new_range
);
4513 gtk_sheet_draw_border (GtkSheet
*sheet
, GtkSheetRange new_range
)
4518 gint x
,y
,width
,height
;
4520 widget
= GTK_WIDGET(sheet
);
4522 x
=COLUMN_LEFT_XPIXEL(sheet
,new_range
.col0
);
4523 y
=ROW_TOP_YPIXEL(sheet
,new_range
.row0
);
4524 width
=COLUMN_LEFT_XPIXEL(sheet
,new_range
.coli
)-x
+
4525 sheet
->column
[new_range
.coli
].width
;
4526 height
=ROW_TOP_YPIXEL(sheet
,new_range
.rowi
)-y
+
4527 sheet
->row
[new_range
.rowi
].height
;
4529 area
.x
=COLUMN_LEFT_XPIXEL(sheet
, MIN_VISIBLE_COLUMN(sheet
));
4530 area
.y
=ROW_TOP_YPIXEL(sheet
, MIN_VISIBLE_ROW(sheet
));
4531 area
.width
=sheet
->sheet_window_width
;
4532 area
.height
=sheet
->sheet_window_height
;
4538 if(width
>area
.width
) width
=area
.width
+10;
4543 if(height
>area
.height
) height
=area
.height
+10;
4545 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &area
);
4547 for(i
=-1; i
<=1; ++i
)
4548 gdk_draw_rectangle (sheet
->sheet_window
,
4552 width
-2*i
,height
-2*i
);
4554 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
4556 gtk_sheet_draw_corners(sheet
, new_range
);
4561 gtk_sheet_draw_corners(GtkSheet
*sheet
, GtkSheetRange range
)
4566 if(gtk_sheet_cell_isvisible(sheet
, range
.row0
, range
.col0
)){
4567 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
4568 y
=ROW_TOP_YPIXEL(sheet
,range
.row0
);
4569 gdk_draw_pixmap(sheet
->sheet_window
,
4570 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4578 gdk_draw_rectangle (sheet
->sheet_window
,
4585 if(gtk_sheet_cell_isvisible(sheet
, range
.row0
, range
.coli
) ||
4586 sheet
->state
== GTK_SHEET_COLUMN_SELECTED
){
4587 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.coli
)+
4588 sheet
->column
[range
.coli
].width
;
4589 y
=ROW_TOP_YPIXEL(sheet
,range
.row0
);
4591 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
4593 y
= ROW_TOP_YPIXEL(sheet
, sheet
->view
.row0
)+3;
4596 gdk_draw_pixmap(sheet
->sheet_window
,
4597 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4605 gdk_draw_rectangle (sheet
->sheet_window
,
4608 x
-width
+width
/2,y
-width
+width
/2,
4612 if(gtk_sheet_cell_isvisible(sheet
, range
.rowi
, range
.col0
) ||
4613 sheet
->state
== GTK_SHEET_ROW_SELECTED
){
4614 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.col0
);
4615 y
=ROW_TOP_YPIXEL(sheet
,range
.rowi
)+
4616 sheet
->row
[range
.rowi
].height
;
4618 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
4620 x
= COLUMN_LEFT_XPIXEL(sheet
, sheet
->view
.col0
)+3;
4623 gdk_draw_pixmap(sheet
->sheet_window
,
4624 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4632 gdk_draw_rectangle (sheet
->sheet_window
,
4635 x
-width
+width
/2,y
-width
+width
/2,
4639 if(gtk_sheet_cell_isvisible(sheet
, range
.rowi
, range
.coli
)){
4640 x
=COLUMN_LEFT_XPIXEL(sheet
,range
.coli
)+
4641 sheet
->column
[range
.coli
].width
;
4642 y
=ROW_TOP_YPIXEL(sheet
,range
.rowi
)+
4643 sheet
->row
[range
.rowi
].height
;
4645 if(sheet
->state
== GTK_SHEET_RANGE_SELECTED
) width
= 3;
4646 if(sheet
->state
== GTK_SHEET_NORMAL
) width
= 3;
4647 gdk_draw_pixmap(sheet
->sheet_window
,
4648 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
4656 gdk_draw_rectangle (sheet
->sheet_window
,
4659 x
-width
+width
/2,y
-width
+width
/2,
4668 gtk_sheet_real_select_range (GtkSheet
* sheet
,
4669 GtkSheetRange
* range
)
4674 g_return_if_fail (sheet
!= NULL
);
4676 if(range
==NULL
) range
=&sheet
->range
;
4678 if(range
->row0
< 0 || range
->rowi
< 0) return;
4679 if(range
->col0
< 0 || range
->coli
< 0) return;
4683 if(state
==GTK_SHEET_COLUMN_SELECTED
|| state
==GTK_SHEET_RANGE_SELECTED
){
4684 for(i
=sheet
->range
.col0
; i
< range
->col0
; i
++)
4685 column_button_release(sheet
, i
);
4686 for(i
=range
->coli
+1; i
<= sheet
->range
.coli
; i
++)
4687 column_button_release(sheet
, i
);
4688 for(i
=range
->col0
; i
<=range
->coli
; i
++){
4689 column_button_set(sheet
, i
);
4693 if(state
==GTK_SHEET_ROW_SELECTED
|| state
==GTK_SHEET_RANGE_SELECTED
){
4694 for(i
=sheet
->range
.row0
; i
< range
->row0
; i
++)
4695 row_button_release(sheet
, i
);
4696 for(i
=range
->rowi
+1; i
<= sheet
->range
.rowi
; i
++)
4697 row_button_release(sheet
, i
);
4698 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4699 row_button_set(sheet
, i
);
4703 if(range
->coli
!= sheet
->range
.coli
|| range
->col0
!= sheet
->range
.col0
||
4704 range
->rowi
!= sheet
->range
.rowi
|| range
->row0
!= sheet
->range
.row0
)
4707 gtk_sheet_new_selection(sheet
, range
);
4709 sheet
->range
.col0
=range
->col0
;
4710 sheet
->range
.coli
=range
->coli
;
4711 sheet
->range
.row0
=range
->row0
;
4712 sheet
->range
.rowi
=range
->rowi
;
4717 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4718 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
4721 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[SELECT_RANGE
], range
);
4725 gtk_sheet_select_range(GtkSheet
* sheet
, const GtkSheetRange
*range
)
4727 g_return_if_fail (sheet
!= NULL
);
4729 if(range
==NULL
) range
=&sheet
->range
;
4731 if(range
->row0
< 0 || range
->rowi
< 0) return;
4732 if(range
->col0
< 0 || range
->coli
< 0) return;
4734 if(sheet
->state
!= GTK_SHEET_NORMAL
)
4735 gtk_sheet_real_unselect_range(sheet
, NULL
);
4738 gboolean veto
= TRUE
;
4739 veto
= gtk_sheet_deactivate_cell(sheet
);
4743 sheet
->range
.row0
=range
->row0
;
4744 sheet
->range
.rowi
=range
->rowi
;
4745 sheet
->range
.col0
=range
->col0
;
4746 sheet
->range
.coli
=range
->coli
;
4747 sheet
->active_cell
.row
=range
->row0
;
4748 sheet
->active_cell
.col
=range
->col0
;
4749 sheet
->selection_cell
.row
=range
->rowi
;
4750 sheet
->selection_cell
.col
=range
->coli
;
4752 sheet
->state
= GTK_SHEET_RANGE_SELECTED
;
4753 gtk_sheet_real_select_range(sheet
, NULL
);
4758 gtk_sheet_unselect_range (GtkSheet
* sheet
)
4760 gtk_sheet_real_unselect_range(sheet
, NULL
);
4761 sheet
->state
= GTK_STATE_NORMAL
;
4762 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
);
4767 gtk_sheet_real_unselect_range (GtkSheet
* sheet
,
4768 const GtkSheetRange
*range
)
4772 g_return_if_fail (sheet
!= NULL
);
4773 g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)));
4776 range
=&sheet
->range
;
4779 if(range
->row0
< 0 || range
->rowi
< 0) return;
4780 if(range
->col0
< 0 || range
->coli
< 0) return;
4782 if (gtk_sheet_range_isvisible (sheet
, *range
)){
4783 gtk_sheet_draw_backing_pixmap(sheet
, *range
);
4786 for(i
=range
->col0
; i
<=range
->coli
; i
++){
4787 column_button_release(sheet
, i
);
4790 for(i
=range
->row0
; i
<=range
->rowi
; i
++){
4791 row_button_release(sheet
, i
);
4798 gtk_sheet_expose (GtkWidget
* widget
,
4799 GdkEventExpose
* event
)
4802 GtkSheetRange range
;
4805 printf("---> Entered gtk_sheet_expose ... must have received expose_event\n");
4808 g_return_val_if_fail (widget
!= NULL
, FALSE
);
4809 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
4810 g_return_val_if_fail (event
!= NULL
, FALSE
);
4812 sheet
= GTK_SHEET (widget
);
4814 if (GTK_WIDGET_DRAWABLE (widget
))
4816 range
.row0
=ROW_FROM_YPIXEL(sheet
,event
->area
.y
);
4817 range
.col0
=COLUMN_FROM_XPIXEL(sheet
,event
->area
.x
);
4818 range
.rowi
=ROW_FROM_YPIXEL(sheet
,event
->area
.y
+event
->area
.height
);
4819 range
.coli
=COLUMN_FROM_XPIXEL(sheet
,event
->area
.x
+event
->area
.width
);
4821 /* exposure events on the sheet */
4823 if( (event
->window
== sheet
->row_title_window
) && sheet
->row_titles_visible
){
4824 size_allocate_row_title_buttons(sheet
);
4827 if( (event
->window
== sheet
->column_title_window
) && sheet
->column_titles_visible
){
4828 size_allocate_column_title_buttons(sheet
);
4831 if (event
->window
== sheet
->sheet_window
){
4832 gtk_sheet_draw_backing_pixmap(sheet
, range
);
4834 if(sheet
->state
!= GTK_SHEET_NORMAL
){
4835 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
4836 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->range
);
4837 if(GTK_SHEET_IN_RESIZE(sheet
) || GTK_SHEET_IN_DRAG(sheet
))
4838 gtk_sheet_draw_backing_pixmap(sheet
, sheet
->drag_range
);
4840 if(gtk_sheet_range_isvisible(sheet
, sheet
->range
))
4841 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
4842 if(GTK_SHEET_IN_RESIZE(sheet
) || GTK_SHEET_IN_DRAG(sheet
))
4843 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4846 if((!GTK_SHEET_IN_XDRAG(sheet
)) && (!GTK_SHEET_IN_YDRAG(sheet
))){
4847 if(sheet
->state
== GTK_SHEET_NORMAL
){
4848 gtk_sheet_draw_active_cell(sheet
);
4849 if(!GTK_SHEET_IN_SELECTION(sheet
))
4850 gtk_widget_queue_draw(sheet
->sheet_entry
);
4859 if(sheet
->state
!= GTK_SHEET_NORMAL
&& GTK_SHEET_IN_SELECTION(sheet
))
4860 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4862 (* GTK_WIDGET_CLASS (parent_class
)->expose_event
) (widget
, event
);
4865 printf("<--- Leaving gtk_sheet_expose\n");
4873 gtk_sheet_button_press (GtkWidget
* widget
,
4874 GdkEventButton
* event
)
4877 GdkModifierType mods
;
4878 gint x
, y
, row
, column
;
4881 g_return_val_if_fail (widget
!= NULL
, FALSE
);
4882 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
4883 g_return_val_if_fail (event
!= NULL
, FALSE
);
4885 if(event
->type
!= GDK_BUTTON_PRESS
) return TRUE
;
4886 gdk_window_get_pointer(widget
->window
, NULL
, NULL
, &mods
);
4887 if(!(mods
& GDK_BUTTON1_MASK
)) return TRUE
;
4889 sheet
= GTK_SHEET (widget
);
4891 /* press on resize windows */
4892 if (event
->window
== sheet
->column_title_window
&&
4893 gtk_sheet_columns_resizable(sheet
))
4895 gtk_widget_get_pointer (widget
, &sheet
->x_drag
, NULL
);
4896 if(POSSIBLE_XDRAG(sheet
, sheet
->x_drag
, &sheet
->drag_cell
.col
)){
4898 gtk_sheet_column_size_request(sheet
, sheet
->drag_cell
.col
, &req
);
4899 GTK_SHEET_SET_FLAGS (sheet
, GTK_SHEET_IN_XDRAG
);
4900 gdk_pointer_grab (sheet
->column_title_window
, FALSE
,
4901 GDK_POINTER_MOTION_HINT_MASK
|
4902 GDK_BUTTON1_MOTION_MASK
|
4903 GDK_BUTTON_RELEASE_MASK
,
4904 NULL
, NULL
, event
->time
);
4906 draw_xor_vline (sheet
);
4911 if (event
->window
== sheet
->row_title_window
&& gtk_sheet_rows_resizable(sheet
))
4913 gtk_widget_get_pointer (widget
, NULL
, &sheet
->y_drag
);
4915 if(POSSIBLE_YDRAG(sheet
, sheet
->y_drag
, &sheet
->drag_cell
.row
)){
4917 gtk_sheet_row_size_request(sheet
, sheet
->drag_cell
.row
, &req
);
4918 GTK_SHEET_SET_FLAGS (sheet
, GTK_SHEET_IN_YDRAG
);
4919 gdk_pointer_grab (sheet
->row_title_window
, FALSE
,
4920 GDK_POINTER_MOTION_HINT_MASK
|
4921 GDK_BUTTON1_MOTION_MASK
|
4922 GDK_BUTTON_RELEASE_MASK
,
4923 NULL
, NULL
, event
->time
);
4925 draw_xor_hline (sheet
);
4930 /* selections on the sheet */
4931 if(event
->window
== sheet
->sheet_window
){
4932 gtk_widget_get_pointer (widget
, &x
, &y
);
4933 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
4934 gdk_pointer_grab (sheet
->sheet_window
, FALSE
,
4935 GDK_POINTER_MOTION_HINT_MASK
|
4936 GDK_BUTTON1_MOTION_MASK
|
4937 GDK_BUTTON_RELEASE_MASK
,
4938 NULL
, NULL
, event
->time
);
4939 gtk_grab_add(GTK_WIDGET(sheet
));
4940 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
4941 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
4942 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
4943 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
4945 if(sheet
->selection_mode
!= GTK_SELECTION_SINGLE
&&
4946 sheet
->cursor_drag
->type
==GDK_SIZING
&&
4947 !GTK_SHEET_IN_SELECTION(sheet
) && !GTK_SHEET_IN_RESIZE(sheet
)){
4948 if(sheet
->state
==GTK_STATE_NORMAL
) {
4949 row
=sheet
->active_cell
.row
;
4950 column
=sheet
->active_cell
.col
;
4951 if(!gtk_sheet_deactivate_cell(sheet
)) return FALSE
;
4952 sheet
->active_cell
.row
=row
;
4953 sheet
->active_cell
.col
=column
;
4954 sheet
->drag_range
=sheet
->range
;
4955 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
4956 gtk_sheet_select_range(sheet
, &sheet
->drag_range
);
4960 if(row
> sheet
->range
.rowi
) row
--;
4961 if(column
> sheet
->range
.coli
) column
--;
4962 sheet
->drag_cell
.row
= row
;
4963 sheet
->drag_cell
.col
= column
;
4964 sheet
->drag_range
=sheet
->range
;
4965 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4966 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_RESIZE
);
4968 else if(sheet
->cursor_drag
->type
==GDK_TOP_LEFT_ARROW
&&
4969 !GTK_SHEET_IN_SELECTION(sheet
) && !GTK_SHEET_IN_DRAG(sheet
)) {
4970 if(sheet
->state
==GTK_STATE_NORMAL
) {
4971 row
=sheet
->active_cell
.row
;
4972 column
=sheet
->active_cell
.col
;
4973 if(!gtk_sheet_deactivate_cell(sheet
)) return FALSE
;
4974 sheet
->active_cell
.row
=row
;
4975 sheet
->active_cell
.col
=column
;
4976 sheet
->drag_range
=sheet
->range
;
4977 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
4978 gtk_sheet_select_range(sheet
, &sheet
->drag_range
);
4982 if(row
< sheet
->range
.row0
) row
++;
4983 if(row
> sheet
->range
.rowi
) row
--;
4984 if(column
< sheet
->range
.col0
) column
++;
4985 if(column
> sheet
->range
.coli
) column
--;
4986 sheet
->drag_cell
.row
=row
;
4987 sheet
->drag_cell
.col
=column
;
4988 sheet
->drag_range
=sheet
->range
;
4989 draw_xor_rectangle(sheet
, sheet
->drag_range
);
4990 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_DRAG
);
4994 gtk_sheet_click_cell(sheet
, row
, column
, &veto
);
4995 if(veto
) GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5000 if(event
->window
== sheet
->column_title_window
){
5001 gtk_widget_get_pointer (widget
, &x
, &y
);
5002 column
= COLUMN_FROM_XPIXEL(sheet
, x
);
5003 if(sheet
->column
[column
].is_sensitive
){;
5004 gtk_sheet_click_cell(sheet
, -1, column
, &veto
);
5005 gtk_grab_add(GTK_WIDGET(sheet
));
5006 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
5007 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
5008 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
5009 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5010 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5014 if(event
->window
== sheet
->row_title_window
){
5015 gtk_widget_get_pointer (widget
, &x
, &y
);
5016 row
= ROW_FROM_YPIXEL(sheet
, y
);
5017 if(sheet
->row
[row
].is_sensitive
){
5018 gtk_sheet_click_cell(sheet
, row
, -1, &veto
);
5019 gtk_grab_add(GTK_WIDGET(sheet
));
5020 sheet
->timer
=gtk_timeout_add(TIMEOUT_SCROLL
, gtk_sheet_scroll
, sheet
);
5021 GTK_WIDGET_UNSET_FLAGS(sheet
->sheet_entry
, GTK_HAS_FOCUS
);
5022 GTK_WIDGET_SET_FLAGS(GTK_SHEET(sheet
), GTK_HAS_FOCUS
);
5023 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5024 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5032 gtk_sheet_scroll(gpointer data
)
5035 gint x
,y
,row
,column
;
5038 sheet
=GTK_SHEET(data
);
5040 GDK_THREADS_ENTER();
5042 gtk_widget_get_pointer (GTK_WIDGET(sheet
), &x
, &y
);
5043 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
5047 if(GTK_SHEET_IN_SELECTION(sheet
))
5048 gtk_sheet_extend_selection(sheet
, row
, column
);
5050 if(GTK_SHEET_IN_DRAG(sheet
) || GTK_SHEET_IN_RESIZE(sheet
)){
5051 move
=gtk_sheet_move_query(sheet
, row
, column
);
5052 if(move
) draw_xor_rectangle(sheet
, sheet
->drag_range
);
5055 GDK_THREADS_LEAVE();
5062 gtk_sheet_click_cell(GtkSheet
*sheet
, gint row
, gint column
, gboolean
*veto
)
5066 if(row
> sheet
->maxrow
|| column
> sheet
->maxcol
){
5071 if(column
>= 0 && row
>= 0)
5072 if(!sheet
->column
[column
].is_visible
|| !sheet
->row
[row
].is_visible
)
5078 _gtkextra_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[TRAVERSE
],
5079 sheet
->active_cell
.row
, sheet
->active_cell
.col
,
5080 &row
, &column
, veto
);
5083 if(sheet
->state
== GTK_STATE_NORMAL
) return;
5085 row
= sheet
->active_cell
.row
;
5086 column
= sheet
->active_cell
.col
;
5087 gtk_sheet_activate_cell(sheet
, row
, column
);
5091 if(row
== -1 && column
>= 0){
5092 if(gtk_sheet_autoscroll(sheet
))
5093 gtk_sheet_move_query(sheet
, row
, column
);
5094 gtk_sheet_select_column(sheet
, column
);
5097 if(column
== -1 && row
>= 0){
5098 if(gtk_sheet_autoscroll(sheet
))
5099 gtk_sheet_move_query(sheet
, row
, column
);
5100 gtk_sheet_select_row(sheet
, row
);
5104 if(row
==-1 && column
==-1){
5105 sheet
->range
.row0
=0;
5106 sheet
->range
.col0
=0;
5107 sheet
->range
.rowi
=sheet
->maxrow
;
5108 sheet
->range
.coli
=sheet
->maxcol
;
5109 sheet
->active_cell
.row
=0;
5110 sheet
->active_cell
.col
=0;
5111 gtk_sheet_select_range(sheet
, NULL
);
5115 if(row
!=-1 && column
!=-1){
5116 if(sheet
->state
!= GTK_SHEET_NORMAL
){
5117 sheet
->state
= GTK_SHEET_NORMAL
;
5118 gtk_sheet_real_unselect_range(sheet
, NULL
);
5122 if(!gtk_sheet_deactivate_cell(sheet
)){
5128 if(gtk_sheet_autoscroll(sheet
))
5129 gtk_sheet_move_query(sheet
, row
, column
);
5130 sheet
->active_cell
.row
=row
;
5131 sheet
->active_cell
.col
=column
;
5132 sheet
->selection_cell
.row
=row
;
5133 sheet
->selection_cell
.col
=column
;
5134 sheet
->range
.row0
=row
;
5135 sheet
->range
.col0
=column
;
5136 sheet
->range
.rowi
=row
;
5137 sheet
->range
.coli
=column
;
5138 sheet
->state
=GTK_SHEET_NORMAL
;
5139 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5140 gtk_sheet_draw_active_cell(sheet
);
5144 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5145 sheet
->active_cell
.col
);
5149 gtk_sheet_button_release (GtkWidget
* widget
,
5150 GdkEventButton
* event
)
5155 sheet
=GTK_SHEET(widget
);
5157 /* release on resize windows */
5158 if (GTK_SHEET_IN_XDRAG (sheet
)){
5159 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_XDRAG
);
5160 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_SELECTION
);
5161 gtk_widget_get_pointer (widget
, &x
, NULL
);
5162 gdk_pointer_ungrab (event
->time
);
5163 draw_xor_vline (sheet
);
5165 gtk_sheet_set_column_width (sheet
, sheet
->drag_cell
.col
, new_column_width (sheet
, sheet
->drag_cell
.col
, &x
));
5166 sheet
->old_hadjustment
= -1.;
5167 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
), "value_changed");
5171 if (GTK_SHEET_IN_YDRAG (sheet
)){
5172 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_YDRAG
);
5173 GTK_SHEET_UNSET_FLAGS (sheet
, GTK_SHEET_IN_SELECTION
);
5174 gtk_widget_get_pointer (widget
, NULL
, &y
);
5175 gdk_pointer_ungrab (event
->time
);
5176 draw_xor_hline (sheet
);
5178 gtk_sheet_set_row_height (sheet
, sheet
->drag_cell
.row
, new_row_height (sheet
, sheet
->drag_cell
.row
, &y
));
5179 sheet
->old_vadjustment
= -1.;
5180 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
), "value_changed");
5185 if (GTK_SHEET_IN_DRAG(sheet
)){
5186 GtkSheetRange old_range
;
5187 draw_xor_rectangle(sheet
, sheet
->drag_range
);
5188 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_DRAG
);
5189 gdk_pointer_ungrab (event
->time
);
5191 gtk_sheet_real_unselect_range(sheet
, NULL
);
5193 sheet
->active_cell
.row
= sheet
->active_cell
.row
+
5194 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5195 sheet
->active_cell
.col
= sheet
->active_cell
.col
+
5196 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5197 sheet
->selection_cell
.row
= sheet
->selection_cell
.row
+
5198 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5199 sheet
->selection_cell
.col
= sheet
->selection_cell
.col
+
5200 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5201 old_range
=sheet
->range
;
5202 sheet
->range
=sheet
->drag_range
;
5203 sheet
->drag_range
=old_range
;
5204 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[MOVE_RANGE
],
5205 &sheet
->drag_range
, &sheet
->range
);
5206 gtk_sheet_select_range(sheet
, &sheet
->range
);
5209 if (GTK_SHEET_IN_RESIZE(sheet
)){
5210 GtkSheetRange old_range
;
5211 draw_xor_rectangle(sheet
, sheet
->drag_range
);
5212 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_RESIZE
);
5213 gdk_pointer_ungrab (event
->time
);
5215 gtk_sheet_real_unselect_range(sheet
, NULL
);
5217 sheet
->active_cell
.row
= sheet
->active_cell
.row
+
5218 (sheet
->drag_range
.row0
- sheet
->range
.row0
);
5219 sheet
->active_cell
.col
= sheet
->active_cell
.col
+
5220 (sheet
->drag_range
.col0
- sheet
->range
.col0
);
5221 if(sheet
->drag_range
.row0
< sheet
->range
.row0
)
5222 sheet
->selection_cell
.row
= sheet
->drag_range
.row0
;
5223 if(sheet
->drag_range
.rowi
>= sheet
->range
.rowi
)
5224 sheet
->selection_cell
.row
= sheet
->drag_range
.rowi
;
5225 if(sheet
->drag_range
.col0
< sheet
->range
.col0
)
5226 sheet
->selection_cell
.col
= sheet
->drag_range
.col0
;
5227 if(sheet
->drag_range
.coli
>= sheet
->range
.coli
)
5228 sheet
->selection_cell
.col
= sheet
->drag_range
.coli
;
5229 old_range
= sheet
->range
;
5230 sheet
->range
= sheet
->drag_range
;
5231 sheet
->drag_range
= old_range
;
5233 if(sheet
->state
==GTK_STATE_NORMAL
) sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5234 gtk_signal_emit(GTK_OBJECT(sheet
),sheet_signals
[RESIZE_RANGE
],
5235 &sheet
->drag_range
, &sheet
->range
);
5236 gtk_sheet_select_range(sheet
, &sheet
->range
);
5239 if(sheet
->state
== GTK_SHEET_NORMAL
&& GTK_SHEET_IN_SELECTION(sheet
)){
5240 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5241 gdk_pointer_ungrab (event
->time
);
5242 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5243 sheet
->active_cell
.col
);
5246 if(GTK_SHEET_IN_SELECTION
)
5247 gdk_pointer_ungrab (event
->time
);
5249 gtk_timeout_remove(sheet
->timer
);
5250 gtk_grab_remove(GTK_WIDGET(sheet
));
5252 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5258 gtk_sheet_motion (GtkWidget
* widget
,
5259 GdkEventMotion
* event
)
5262 GdkModifierType mods
;
5263 GdkCursorType new_cursor
;
5264 gint x
, y
, row
, column
;
5266 g_return_val_if_fail (widget
!= NULL
, FALSE
);
5267 g_return_val_if_fail (GTK_IS_SHEET (widget
), FALSE
);
5268 g_return_val_if_fail (event
!= NULL
, FALSE
);
5271 sheet
= GTK_SHEET (widget
);
5274 /* selections on the sheet */
5278 if(event
->window
== sheet
->column_title_window
&& gtk_sheet_columns_resizable(sheet
)){
5279 gtk_widget_get_pointer(widget
, &x
, &y
);
5280 if(!GTK_SHEET_IN_SELECTION(sheet
) && POSSIBLE_XDRAG(sheet
, x
, &column
)){
5281 new_cursor
=GDK_SB_H_DOUBLE_ARROW
;
5282 if(new_cursor
!= sheet
->cursor_drag
->type
){
5283 gdk_cursor_destroy(sheet
->cursor_drag
);
5284 sheet
->cursor_drag
=gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW
);
5285 gdk_window_set_cursor(sheet
->column_title_window
,sheet
->cursor_drag
);
5288 new_cursor
=GDK_TOP_LEFT_ARROW
;
5289 if(!GTK_SHEET_IN_XDRAG(sheet
) && new_cursor
!= sheet
->cursor_drag
->type
){
5290 gdk_cursor_destroy(sheet
->cursor_drag
);
5291 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5292 gdk_window_set_cursor(sheet
->column_title_window
,sheet
->cursor_drag
);
5297 if(event
->window
== sheet
->row_title_window
&& gtk_sheet_rows_resizable(sheet
)){
5298 gtk_widget_get_pointer(widget
, &x
, &y
);
5299 if(!GTK_SHEET_IN_SELECTION(sheet
) && POSSIBLE_YDRAG(sheet
,y
, &column
)){
5300 new_cursor
=GDK_SB_V_DOUBLE_ARROW
;
5301 if(new_cursor
!= sheet
->cursor_drag
->type
){
5302 gdk_cursor_destroy(sheet
->cursor_drag
);
5303 sheet
->cursor_drag
=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW
);
5304 gdk_window_set_cursor(sheet
->row_title_window
,sheet
->cursor_drag
);
5307 new_cursor
=GDK_TOP_LEFT_ARROW
;
5308 if(!GTK_SHEET_IN_YDRAG(sheet
) && new_cursor
!= sheet
->cursor_drag
->type
){
5309 gdk_cursor_destroy(sheet
->cursor_drag
);
5310 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5311 gdk_window_set_cursor(sheet
->row_title_window
,sheet
->cursor_drag
);
5316 new_cursor
=GDK_PLUS
;
5317 if(!POSSIBLE_DRAG(sheet
,x
,y
,&row
,&column
) && !GTK_SHEET_IN_DRAG(sheet
) &&
5318 !POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) && !GTK_SHEET_IN_RESIZE(sheet
) &&
5319 event
->window
== sheet
->sheet_window
&&
5320 new_cursor
!= sheet
->cursor_drag
->type
){
5321 gdk_cursor_destroy(sheet
->cursor_drag
);
5322 sheet
->cursor_drag
=gdk_cursor_new(GDK_PLUS
);
5323 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5326 new_cursor
=GDK_TOP_LEFT_ARROW
;
5327 if(!(POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) || GTK_SHEET_IN_RESIZE(sheet
)) &&
5328 (POSSIBLE_DRAG(sheet
, x
,y
,&row
,&column
) || GTK_SHEET_IN_DRAG(sheet
)) &&
5329 event
->window
== sheet
->sheet_window
&&
5330 new_cursor
!= sheet
->cursor_drag
->type
){
5331 gdk_cursor_destroy(sheet
->cursor_drag
);
5332 sheet
->cursor_drag
=gdk_cursor_new(GDK_TOP_LEFT_ARROW
);
5333 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5336 new_cursor
=GDK_SIZING
;
5337 if(!GTK_SHEET_IN_DRAG(sheet
) &&
5338 (POSSIBLE_RESIZE(sheet
,x
,y
,&row
,&column
) || GTK_SHEET_IN_RESIZE(sheet
)) &&
5339 event
->window
== sheet
->sheet_window
&&
5340 new_cursor
!= sheet
->cursor_drag
->type
){
5341 gdk_cursor_destroy(sheet
->cursor_drag
);
5342 sheet
->cursor_drag
=gdk_cursor_new(GDK_SIZING
);
5343 gdk_window_set_cursor(sheet
->sheet_window
,sheet
->cursor_drag
);
5346 gdk_window_get_pointer (widget
->window
, &x
, &y
, &mods
);
5347 if(!(mods
& GDK_BUTTON1_MASK
)) return FALSE
;
5349 if (GTK_SHEET_IN_XDRAG (sheet
)){
5350 if (event
->is_hint
|| event
->window
!= widget
->window
)
5351 gtk_widget_get_pointer (widget
, &x
, NULL
);
5355 new_column_width (sheet
, sheet
->drag_cell
.col
, &x
);
5356 if (x
!= sheet
->x_drag
)
5358 draw_xor_vline (sheet
);
5360 draw_xor_vline (sheet
);
5365 if (GTK_SHEET_IN_YDRAG (sheet
)){
5366 if (event
->is_hint
|| event
->window
!= widget
->window
)
5367 gtk_widget_get_pointer (widget
, NULL
, &y
);
5371 new_row_height (sheet
, sheet
->drag_cell
.row
, &y
);
5372 if (y
!= sheet
->y_drag
)
5374 draw_xor_hline (sheet
);
5376 draw_xor_hline (sheet
);
5381 if (GTK_SHEET_IN_DRAG(sheet
)){
5383 column
=COLUMN_FROM_XPIXEL(sheet
,x
)-sheet
->drag_cell
.col
;
5384 row
=ROW_FROM_YPIXEL(sheet
,y
)-sheet
->drag_cell
.row
;
5385 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) row
=0;
5386 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) column
=0;
5390 if(aux
.row0
+row
>= 0 && aux
.rowi
+row
<= sheet
->maxrow
&&
5391 aux
.col0
+column
>= 0 && aux
.coli
+column
<= sheet
->maxcol
){
5392 aux
=sheet
->drag_range
;
5393 sheet
->drag_range
.row0
=sheet
->range
.row0
+row
;
5394 sheet
->drag_range
.col0
=sheet
->range
.col0
+column
;
5395 sheet
->drag_range
.rowi
=sheet
->range
.rowi
+row
;
5396 sheet
->drag_range
.coli
=sheet
->range
.coli
+column
;
5397 if(aux
.row0
!= sheet
->drag_range
.row0
||
5398 aux
.col0
!= sheet
->drag_range
.col0
){
5399 draw_xor_rectangle (sheet
, aux
);
5400 draw_xor_rectangle (sheet
, sheet
->drag_range
);
5406 if (GTK_SHEET_IN_RESIZE(sheet
)){
5410 if(abs(x
-COLUMN_LEFT_XPIXEL(sheet
,sheet
->drag_cell
.col
)) >
5411 abs(y
-ROW_TOP_YPIXEL(sheet
,sheet
->drag_cell
.row
))) v_h
=2;
5413 column
=COLUMN_FROM_XPIXEL(sheet
,x
)-sheet
->drag_cell
.col
;
5414 row
=ROW_FROM_YPIXEL(sheet
,y
)-sheet
->drag_cell
.row
;
5415 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) row
=0;
5416 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) column
=0;
5421 if(row
< sheet
->range
.row0
- sheet
->range
.rowi
- 1)
5422 row
=row
+(sheet
->range
.rowi
-sheet
->range
.row0
+ 1);
5423 else if(row
<0) row
=0;
5425 if(column
< sheet
->range
.col0
- sheet
->range
.coli
- 1)
5426 column
=column
+(sheet
->range
.coli
-sheet
->range
.col0
+ 1);
5427 else if(column
<0) column
=0;
5434 if(aux
.row0
+row
>= 0 && aux
.rowi
+row
<= sheet
->maxrow
&&
5435 aux
.col0
+column
>= 0 && aux
.coli
+column
<= sheet
->maxcol
){
5437 aux
=sheet
->drag_range
;
5438 sheet
->drag_range
=sheet
->range
;
5440 if(row
<0) sheet
->drag_range
.row0
=sheet
->range
.row0
+row
;
5441 if(row
>0) sheet
->drag_range
.rowi
=sheet
->range
.rowi
+row
;
5442 if(column
<0) sheet
->drag_range
.col0
=sheet
->range
.col0
+column
;
5443 if(column
>0) sheet
->drag_range
.coli
=sheet
->range
.coli
+column
;
5445 if(aux
.row0
!= sheet
->drag_range
.row0
||
5446 aux
.rowi
!= sheet
->drag_range
.rowi
||
5447 aux
.col0
!= sheet
->drag_range
.col0
||
5448 aux
.coli
!= sheet
->drag_range
.coli
){
5449 draw_xor_rectangle (sheet
, aux
);
5450 draw_xor_rectangle (sheet
, sheet
->drag_range
);
5458 gtk_sheet_get_pixel_info (sheet
, x
, y
, &row
, &column
);
5460 if(sheet
->state
==GTK_SHEET_NORMAL
&& row
==sheet
->active_cell
.row
&&
5461 column
==sheet
->active_cell
.col
) return TRUE
;
5463 if(GTK_SHEET_IN_SELECTION(sheet
) && mods
&GDK_BUTTON1_MASK
)
5464 gtk_sheet_extend_selection(sheet
, row
, column
);
5470 gtk_sheet_move_query(GtkSheet
*sheet
, gint row
, gint column
)
5472 gint row_move
, column_move
;
5473 gfloat row_align
, col_align
;
5474 guint height
, width
;
5476 gint new_col
= column
;
5483 height
= sheet
->sheet_window_height
;
5484 width
= sheet
->sheet_window_width
;
5486 if(row
>=MAX_VISIBLE_ROW(sheet
) && sheet
->state
!=GTK_SHEET_COLUMN_SELECTED
) {
5488 new_row
= MIN(sheet
->maxrow
, row
+ 1);
5490 if(MAX_VISIBLE_ROW(sheet
) == sheet
->maxrow
&&
5491 ROW_TOP_YPIXEL(sheet
, sheet
->maxrow
) +
5492 sheet
->row
[sheet
->maxrow
].height
< height
){
5497 if(row
<MIN_VISIBLE_ROW(sheet
) && sheet
->state
!=GTK_SHEET_COLUMN_SELECTED
) {
5501 if(column
>=MAX_VISIBLE_COLUMN(sheet
) && sheet
->state
!=GTK_SHEET_ROW_SELECTED
) {
5503 new_col
= MIN(sheet
->maxcol
, column
+ 1);
5505 if(MAX_VISIBLE_COLUMN(sheet
) == sheet
->maxcol
&&
5506 COLUMN_LEFT_XPIXEL(sheet
, sheet
->maxcol
) +
5507 sheet
->column
[sheet
->maxcol
].width
< width
){
5508 column_move
= FALSE
;
5512 if(column
<MIN_VISIBLE_COLUMN(sheet
) && sheet
->state
!=GTK_SHEET_ROW_SELECTED
) {
5517 if(row_move
|| column_move
){
5518 gtk_sheet_moveto(sheet
, new_row
, new_col
, row_align
, col_align
);
5521 return(row_move
|| column_move
);
5525 gtk_sheet_extend_selection(GtkSheet
*sheet
, gint row
, gint column
)
5527 GtkSheetRange range
;
5531 if(row
== sheet
->selection_cell
.row
&& column
== sheet
->selection_cell
.col
)
5534 if(sheet
->selection_mode
== GTK_SELECTION_SINGLE
) return;
5536 gtk_sheet_move_query(sheet
, row
, column
);
5537 gtk_widget_grab_focus(GTK_WIDGET(sheet
));
5539 if(GTK_SHEET_IN_DRAG(sheet
)) return;
5543 switch(sheet
->state
){
5544 case GTK_SHEET_ROW_SELECTED
:
5545 column
= sheet
->maxcol
;
5547 case GTK_SHEET_COLUMN_SELECTED
:
5548 row
= sheet
->maxrow
;
5550 case GTK_SHEET_NORMAL
:
5551 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5552 r
=sheet
->active_cell
.row
;
5553 c
=sheet
->active_cell
.col
;
5554 sheet
->range
.col0
=c
;
5555 sheet
->range
.row0
=r
;
5556 sheet
->range
.coli
=c
;
5557 sheet
->range
.rowi
=r
;
5558 gdk_draw_pixmap(sheet
->sheet_window
,
5559 GTK_WIDGET(sheet
)->style
->fg_gc
[GTK_STATE_NORMAL
],
5561 COLUMN_LEFT_XPIXEL(sheet
,c
)-1,
5562 ROW_TOP_YPIXEL(sheet
,r
)-1,
5563 COLUMN_LEFT_XPIXEL(sheet
,c
)-1,
5564 ROW_TOP_YPIXEL(sheet
,r
)-1,
5565 sheet
->column
[c
].width
+4,
5566 sheet
->row
[r
].height
+4);
5567 gtk_sheet_range_draw_selection(sheet
, sheet
->range
);
5568 case GTK_SHEET_RANGE_SELECTED
:
5569 sheet
->state
=GTK_SHEET_RANGE_SELECTED
;
5572 sheet
->selection_cell
.row
= row
;
5573 sheet
->selection_cell
.col
= column
;
5575 range
.col0
=MIN(column
,sheet
->active_cell
.col
);
5576 range
.coli
=MAX(column
,sheet
->active_cell
.col
);
5577 range
.row0
=MIN(row
,sheet
->active_cell
.row
);
5578 range
.rowi
=MAX(row
,sheet
->active_cell
.row
);
5580 if(range
.row0
!= sheet
->range
.row0
|| range
.rowi
!= sheet
->range
.rowi
||
5581 range
.col0
!= sheet
->range
.col0
|| range
.coli
!= sheet
->range
.coli
||
5582 state
==GTK_SHEET_NORMAL
)
5583 gtk_sheet_real_select_range(sheet
, &range
);
5587 /* Removed by SDB while cleaning up key press behavior */
5590 gtk_sheet_entry_key_press(GtkWidget
*widget
,
5595 printf("Entered gtk_sheet_entry_key_press. . . . . \n");
5598 gtk_signal_emit_by_name(GTK_OBJECT(widget
), "key_press_event", key
, &focus
);
5604 gtk_sheet_key_press(GtkWidget
*widget
,
5610 gboolean extend_selection
= FALSE
;
5612 gboolean force_move
= FALSE
;
5614 gboolean in_selection
= FALSE
;
5615 gboolean veto
= TRUE
;
5618 sheet
= GTK_SHEET(widget
);
5621 printf("\n\nJust entered gtk_sheet_key_press. . . . \n");
5625 if(key
->state
& GDK_CONTROL_MASK
|| key
->keyval
==GDK_Control_L
||
5626 key
->keyval
==GDK_Control_R
) return FALSE
;
5630 if(key->keyval=='c' || key->keyval == 'C' && sheet->state != GTK_STATE_NORMAL)
5631 gtk_sheet_clip_range(sheet, sheet->range);
5632 if(key->keyval=='x' || key->keyval == 'X')
5633 gtk_sheet_unclip_range(sheet);
5638 /* extend_selection is set when shift, ctrl, etc is pressed & held down */
5639 extend_selection
= (key
->state
& GDK_SHIFT_MASK
) || key
->keyval
==GDK_Shift_L
5640 || key
->keyval
==GDK_Shift_R
;
5643 printf(". . . . extend_selection = %d\n", extend_selection
);
5647 in_selection
= GTK_SHEET_IN_SELECTION(sheet
);
5648 GTK_SHEET_UNSET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5651 printf("We are about to enter the switch statement. . .\n");
5654 switch(key
->keyval
){
5655 case GDK_Return
: case GDK_KP_Enter
:
5656 if(sheet
->state
== GTK_SHEET_NORMAL
&&
5657 !GTK_SHEET_IN_SELECTION(sheet
))
5658 gtk_signal_emit_stop_by_name(GTK_OBJECT(gtk_sheet_get_entry(sheet
)),
5660 row
= sheet
->active_cell
.row
;
5661 col
= sheet
->active_cell
.col
;
5662 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5663 row
= MIN_VISIBLE_ROW(sheet
)-1;
5664 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5665 col
= MIN_VISIBLE_COLUMN(sheet
);
5666 if(row
< sheet
->maxrow
){
5668 while(!sheet
->row
[row
].is_visible
&& row
<sheet
->maxrow
) row
++;
5670 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5671 extend_selection
= FALSE
;
5674 case GDK_ISO_Left_Tab
:
5675 case GDK_Left
: /* Left arrow */
5677 printf("In gtk_sheet_key_press, received GDK_Left.\n");
5679 row
= sheet
->active_cell
.row
;
5680 col
= sheet
->active_cell
.col
;
5681 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5682 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5683 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5684 row
= MIN_VISIBLE_ROW(sheet
);
5687 while(!sheet
->column
[col
].is_visible
&& col
>0) col
--;
5690 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5691 extend_selection
= FALSE
;
5695 case GDK_Right
: /* Right arrow */
5697 printf("In gtk_sheet_key_press, received GDK_Right.\n");
5699 row
= sheet
->active_cell
.row
;
5700 col
= sheet
->active_cell
.col
;
5701 if(sheet
->state
== GTK_SHEET_ROW_SELECTED
)
5702 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5703 if(sheet
->state
== GTK_SHEET_COLUMN_SELECTED
)
5704 row
= MIN_VISIBLE_ROW(sheet
);
5705 if(col
< sheet
->maxcol
){
5707 while(!sheet
->column
[col
].is_visible
&& col
<sheet
->maxcol
) col
++;
5709 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5710 extend_selection
= FALSE
;
5713 /* case GDK_BackSpace:
5714 if(sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0){
5715 if(sheet->active_cell.col > 0){
5716 col = sheet->active_cell.col - scroll;
5717 row = sheet->active_cell.row;
5718 while(!sheet->column[col].is_visible && col > 0) col--;
5721 gtk_sheet_click_cell(sheet, row, col, &veto);
5722 extend_selection = FALSE;
5727 scroll
=MAX_VISIBLE_ROW(sheet
)-MIN_VISIBLE_ROW(sheet
)+1;
5728 case GDK_Up
: /* arrow key up */
5729 if(extend_selection
){
5730 if(state
==GTK_STATE_NORMAL
){
5731 row
=sheet
->active_cell
.row
;
5732 col
=sheet
->active_cell
.col
;
5733 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5736 if(sheet
->selection_cell
.row
> 0){
5737 row
= sheet
->selection_cell
.row
- scroll
;
5738 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5740 gtk_sheet_extend_selection(sheet
, row
, sheet
->selection_cell
.col
);
5744 col
= sheet
->active_cell
.col
;
5745 row
= sheet
->active_cell
.row
;
5746 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5747 row
= MIN_VISIBLE_ROW(sheet
);
5748 if(state
==GTK_SHEET_ROW_SELECTED
)
5749 col
= MIN_VISIBLE_COLUMN(sheet
);
5751 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5753 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5754 extend_selection
= FALSE
;
5758 scroll
=MAX_VISIBLE_ROW(sheet
)-MIN_VISIBLE_ROW(sheet
)+1;
5759 case GDK_Down
: /* arrow key down */
5760 if(extend_selection
){
5761 if(state
==GTK_STATE_NORMAL
){
5762 row
=sheet
->active_cell
.row
;
5763 col
=sheet
->active_cell
.col
;
5764 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5767 if(sheet
->selection_cell
.row
< sheet
->maxrow
){
5768 row
= sheet
->selection_cell
.row
+ scroll
;
5769 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5770 row
= MIN(sheet
->maxrow
, row
);
5771 gtk_sheet_extend_selection(sheet
, row
, sheet
->selection_cell
.col
);
5775 col
= sheet
->active_cell
.col
;
5776 row
= sheet
->active_cell
.row
;
5777 if(sheet
->active_cell
.row
< sheet
->maxrow
){
5778 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5779 row
= MIN_VISIBLE_ROW(sheet
)-1;
5780 if(state
==GTK_SHEET_ROW_SELECTED
)
5781 col
= MIN_VISIBLE_COLUMN(sheet
);
5783 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5784 row
= MIN(sheet
->maxrow
, row
);
5786 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5787 extend_selection
= FALSE
;
5792 if(extend_selection
){
5793 if(state
==GTK_STATE_NORMAL
){
5794 row
=sheet
->active_cell
.row
;
5795 col
=sheet
->active_cell
.col
;
5796 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5799 if(sheet
->selection_cell
.col
< sheet
->maxcol
){
5800 col
= sheet
->selection_cell
.col
+ 1;
5801 while(!sheet
->column
[col
].is_visible
&& col
< sheet
->maxcol
) col
++;
5802 gtk_sheet_extend_selection(sheet
, sheet
->selection_cell
.row
, col
);
5806 col
= sheet
->active_cell
.col
;
5807 row
= sheet
->active_cell
.row
;
5808 if(sheet
->active_cell
.col
< sheet
->maxcol
){
5810 if(state
==GTK_SHEET_ROW_SELECTED
)
5811 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5812 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5813 row
= MIN_VISIBLE_ROW(sheet
);
5814 while(!sheet
->column
[col
].is_visible
&& col
< sheet
->maxcol
) col
++;
5815 if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)))) == 0
5817 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5822 extend_selection
= FALSE
;
5827 if(extend_selection
){
5828 if(state
==GTK_STATE_NORMAL
){
5829 row
=sheet
->active_cell
.row
;
5830 col
=sheet
->active_cell
.col
;
5831 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5834 if(sheet
->selection_cell
.col
> 0){
5835 col
= sheet
->selection_cell
.col
- 1;
5836 while(!sheet
->column
[col
].is_visible
&& col
> 0) col
--;
5837 gtk_sheet_extend_selection(sheet
, sheet
->selection_cell
.row
, col
);
5841 col
= sheet
->active_cell
.col
- 1;
5842 row
= sheet
->active_cell
.row
;
5843 if(state
==GTK_SHEET_ROW_SELECTED
)
5844 col
= MIN_VISIBLE_COLUMN(sheet
)-1;
5845 if(state
==GTK_SHEET_COLUMN_SELECTED
)
5846 row
= MIN_VISIBLE_ROW(sheet
);
5847 while(!sheet
->column
[col
].is_visible
&& col
> 0) col
--;
5850 if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)))) == 0
5852 gtk_sheet_click_cell(sheet
, row
, col
, &veto
);
5856 extend_selection
= FALSE
;
5863 while(!sheet
->row
[row
].is_visible
&& row
< sheet
->maxrow
) row
++;
5864 gtk_sheet_click_cell(sheet
, row
, sheet
->active_cell
.col
, &veto
);
5865 extend_selection
= FALSE
;
5870 while(!sheet
->row
[row
].is_visible
&& row
> 0) row
--;
5871 gtk_sheet_click_cell(sheet
, row
, sheet
->active_cell
.col
, &veto
);
5872 extend_selection
= FALSE
;
5877 printf("In gtk_sheet_key_press, after switch, found default case.\n");
5878 printf(" User probably typed letter key or DEL.\n");
5881 GTK_SHEET_SET_FLAGS(sheet
, GTK_SHEET_IN_SELECTION
);
5882 if(extend_selection
) return TRUE
;
5884 if(state
== GTK_SHEET_ROW_SELECTED
)
5885 sheet
->active_cell
.col
=MIN_VISIBLE_COLUMN(sheet
);
5886 if(state
== GTK_SHEET_COLUMN_SELECTED
)
5887 sheet
->active_cell
.row
=MIN_VISIBLE_ROW(sheet
);
5891 if(extend_selection
) return TRUE
;
5893 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
5894 sheet
->active_cell
.col
);
5900 gtk_sheet_size_request (GtkWidget
* widget
,
5901 GtkRequisition
* requisition
)
5905 GtkSheetChild
*child
;
5906 GtkRequisition child_requisition
;
5908 g_return_if_fail (widget
!= NULL
);
5909 g_return_if_fail (GTK_IS_SHEET (widget
));
5910 g_return_if_fail (requisition
!= NULL
);
5912 sheet
= GTK_SHEET (widget
);
5914 requisition
->width
= 3*DEFAULT_COLUMN_WIDTH
;
5915 requisition
->height
= 3*DEFAULT_ROW_HEIGHT(widget
);
5917 /* compute the size of the column title area */
5918 if(sheet
->column_titles_visible
)
5919 requisition
->height
+= sheet
->column_title_area
.height
;
5921 /* compute the size of the row title area */
5922 if(sheet
->row_titles_visible
)
5923 requisition
->width
+= sheet
->row_title_area
.width
;
5925 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
5926 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
5927 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
5928 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
5930 if(!sheet
->column_titles_visible
)
5931 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
5933 if(!sheet
->row_titles_visible
)
5934 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
5936 children
= sheet
->children
;
5939 child
= children
->data
;
5940 children
= g_list_next(children
);
5942 gtk_widget_size_request(child
->widget
, &child_requisition
);
5948 gtk_sheet_size_allocate (GtkWidget
* widget
,
5949 GtkAllocation
* allocation
)
5952 GtkAllocation sheet_allocation
;
5955 g_return_if_fail (widget
!= NULL
);
5956 g_return_if_fail (GTK_IS_SHEET (widget
));
5957 g_return_if_fail (allocation
!= NULL
);
5959 sheet
= GTK_SHEET (widget
);
5960 widget
->allocation
= *allocation
;
5961 border_width
= GTK_CONTAINER(widget
)->border_width
;
5963 if (GTK_WIDGET_REALIZED (widget
))
5964 gdk_window_move_resize (widget
->window
,
5965 allocation
->x
+ border_width
,
5966 allocation
->y
+ border_width
,
5967 allocation
->width
- 2*border_width
,
5968 allocation
->height
- 2*border_width
);
5970 /* use internal allocation structure for all the math
5971 * because it's easier than always subtracting the container
5973 sheet
->internal_allocation
.x
= 0;
5974 sheet
->internal_allocation
.y
= 0;
5975 sheet
->internal_allocation
.width
= allocation
->width
- 2*border_width
;
5976 sheet
->internal_allocation
.height
= allocation
->height
- 2*border_width
;
5978 sheet_allocation
.x
= 0;
5979 sheet_allocation
.y
= 0;
5980 sheet_allocation
.width
= allocation
->width
- 2*border_width
;
5981 sheet_allocation
.height
= allocation
->height
- 2*border_width
;
5983 sheet
->sheet_window_width
= sheet_allocation
.width
;
5984 sheet
->sheet_window_height
= sheet_allocation
.height
;
5986 if (GTK_WIDGET_REALIZED (widget
))
5987 gdk_window_move_resize (sheet
->sheet_window
,
5990 sheet_allocation
.width
,
5991 sheet_allocation
.height
);
5993 /* position the window which holds the column title buttons */
5994 sheet
->column_title_area
.x
= 0;
5995 sheet
->column_title_area
.y
= 0;
5996 if(sheet
->row_titles_visible
)
5997 sheet
->column_title_area
.x
= sheet
->row_title_area
.width
;
5998 sheet
->column_title_area
.width
= sheet_allocation
.width
-
5999 sheet
->column_title_area
.x
;
6000 if(GTK_WIDGET_REALIZED(widget
) && sheet
->column_titles_visible
)
6001 gdk_window_move_resize (sheet
->column_title_window
,
6002 sheet
->column_title_area
.x
,
6003 sheet
->column_title_area
.y
,
6004 sheet
->column_title_area
.width
,
6005 sheet
->column_title_area
.height
);
6007 sheet
->sheet_window_width
= sheet_allocation
.width
;
6008 sheet
->sheet_window_height
= sheet_allocation
.height
;
6010 /* column button allocation */
6011 size_allocate_column_title_buttons (sheet
);
6013 /* position the window which holds the row title buttons */
6014 sheet
->row_title_area
.x
= 0;
6015 sheet
->row_title_area
.y
= 0;
6016 if(sheet
->column_titles_visible
)
6017 sheet
->row_title_area
.y
= sheet
->column_title_area
.height
;
6018 sheet
->row_title_area
.height
= sheet_allocation
.height
-
6019 sheet
->row_title_area
.y
;
6021 if(GTK_WIDGET_REALIZED(widget
) && sheet
->row_titles_visible
)
6022 gdk_window_move_resize (sheet
->row_title_window
,
6023 sheet
->row_title_area
.x
,
6024 sheet
->row_title_area
.y
,
6025 sheet
->row_title_area
.width
,
6026 sheet
->row_title_area
.height
);
6029 /* row button allocation */
6030 size_allocate_row_title_buttons (sheet
);
6032 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
6033 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
6034 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
6035 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
6037 if(!sheet
->column_titles_visible
)
6038 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
6040 if(!sheet
->row_titles_visible
)
6041 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
6043 size_allocate_column_title_buttons(sheet
);
6044 size_allocate_row_title_buttons(sheet
);
6046 /* re-scale backing pixmap */
6047 gtk_sheet_make_backing_pixmap(sheet
, 0, 0);
6048 gtk_sheet_position_children(sheet
);
6050 /* set the scrollbars adjustments */
6051 adjust_scrollbars (sheet
);
6055 size_allocate_column_title_buttons (GtkSheet
* sheet
)
6060 if (!sheet
->column_titles_visible
) return;
6061 if (!GTK_WIDGET_REALIZED (sheet
))
6064 width
= sheet
->sheet_window_width
;
6067 if(sheet
->row_titles_visible
)
6069 width
-= sheet
->row_title_area
.width
;
6070 x
= sheet
->row_title_area
.width
;
6073 if(sheet
->column_title_area
.width
!= width
|| sheet
->column_title_area
.x
!= x
)
6075 sheet
->column_title_area
.width
= width
;
6076 sheet
->column_title_area
.x
= x
;
6077 gdk_window_move_resize (sheet
->column_title_window
,
6078 sheet
->column_title_area
.x
,
6079 sheet
->column_title_area
.y
,
6080 sheet
->column_title_area
.width
,
6081 sheet
->column_title_area
.height
);
6085 if(MAX_VISIBLE_COLUMN(sheet
) == sheet
->maxcol
)
6086 gdk_window_clear_area (sheet
->column_title_window
,
6088 sheet
->column_title_area
.width
,
6089 sheet
->column_title_area
.height
);
6091 if(!GTK_WIDGET_DRAWABLE(sheet
)) return;
6093 for (i
= MIN_VISIBLE_COLUMN(sheet
); i
<= MAX_VISIBLE_COLUMN(sheet
); i
++)
6094 gtk_sheet_button_draw(sheet
,-1,i
);
6098 size_allocate_row_title_buttons (GtkSheet
* sheet
)
6103 if (!sheet
->row_titles_visible
) return;
6104 if (!GTK_WIDGET_REALIZED (sheet
))
6107 height
= sheet
->sheet_window_height
;
6110 if(sheet
->column_titles_visible
)
6112 height
-= sheet
->column_title_area
.height
;
6113 y
= sheet
->column_title_area
.height
;
6116 if(sheet
->row_title_area
.height
!= height
|| sheet
->row_title_area
.y
!= y
){
6117 sheet
->row_title_area
.y
= y
;
6118 sheet
->row_title_area
.height
= height
;
6119 gdk_window_move_resize (sheet
->row_title_window
,
6120 sheet
->row_title_area
.x
,
6121 sheet
->row_title_area
.y
,
6122 sheet
->row_title_area
.width
,
6123 sheet
->row_title_area
.height
);
6125 if(MAX_VISIBLE_ROW(sheet
) == sheet
->maxrow
)
6126 gdk_window_clear_area (sheet
->row_title_window
,
6128 sheet
->row_title_area
.width
,
6129 sheet
->row_title_area
.height
);
6131 if(!GTK_WIDGET_DRAWABLE(sheet
)) return;
6133 for(i
= MIN_VISIBLE_ROW(sheet
); i
<= MAX_VISIBLE_ROW(sheet
); i
++)
6134 gtk_sheet_button_draw(sheet
,i
,-1);
6138 gtk_sheet_recalc_top_ypixels(GtkSheet
*sheet
, gint row
)
6142 cy
= sheet
->column_title_area
.height
;
6143 if(!sheet
->column_titles_visible
) cy
= 0;
6144 for(i
=0; i
<=sheet
->maxrow
; i
++){
6145 sheet
->row
[i
].top_ypixel
=cy
;
6146 if(sheet
->row
[i
].is_visible
) cy
+=sheet
->row
[i
].height
;
6151 gtk_sheet_recalc_left_xpixels(GtkSheet
*sheet
, gint column
)
6155 cx
= sheet
->row_title_area
.width
;
6156 if(!sheet
->row_titles_visible
) cx
= 0;
6157 for(i
=0; i
<=sheet
->maxcol
; i
++){
6158 sheet
->column
[i
].left_xpixel
=cx
;
6159 if(sheet
->column
[i
].is_visible
) cx
+=sheet
->column
[i
].width
;
6167 gtk_sheet_size_allocate_entry(GtkSheet
*sheet
)
6169 GtkAllocation shentry_allocation
;
6170 GtkSheetCellAttr attributes
;
6171 GtkEntry
*sheet_entry
;
6172 GtkStyle
*style
= NULL
, *previous_style
= NULL
;
6174 gint size
, max_size
, text_size
, column_width
;
6177 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
6178 if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
))) return;
6180 sheet_entry
= GTK_ENTRY(gtk_sheet_get_entry(sheet
));
6182 gtk_sheet_get_attributes(sheet
, sheet
->active_cell
.row
, sheet
->active_cell
.col
, &attributes
);
6184 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
)){
6186 if(!GTK_WIDGET(sheet_entry
)->style
)
6187 gtk_widget_ensure_style(GTK_WIDGET(sheet_entry
));
6189 previous_style
= GTK_WIDGET(sheet_entry
)->style
;
6191 style
= gtk_style_copy(previous_style
);
6192 style
->bg
[GTK_STATE_NORMAL
] = attributes
.background
;
6193 style
->fg
[GTK_STATE_NORMAL
] = attributes
.foreground
;
6194 style
->text
[GTK_STATE_NORMAL
] = attributes
.foreground
;
6195 style
->bg
[GTK_STATE_ACTIVE
] = attributes
.background
;
6196 style
->fg
[GTK_STATE_ACTIVE
] = attributes
.foreground
;
6197 style
->text
[GTK_STATE_ACTIVE
] = attributes
.foreground
;
6199 pango_font_description_free(style
->font_desc
);
6200 style
->font_desc
= pango_font_description_copy(attributes
.font_desc
);
6202 GTK_WIDGET(sheet_entry
)->style
= style
;
6203 gtk_widget_size_request(sheet
->sheet_entry
, NULL
);
6204 GTK_WIDGET(sheet_entry
)->style
= previous_style
;
6206 if(style
!= previous_style
){
6207 style
->bg
[GTK_STATE_NORMAL
] = previous_style
->bg
[GTK_STATE_NORMAL
];
6208 style
->fg
[GTK_STATE_NORMAL
] = previous_style
->fg
[GTK_STATE_NORMAL
];
6209 style
->bg
[GTK_STATE_ACTIVE
] = previous_style
->bg
[GTK_STATE_ACTIVE
];
6210 style
->fg
[GTK_STATE_ACTIVE
] = previous_style
->fg
[GTK_STATE_ACTIVE
];
6211 gtk_widget_set_style(GTK_WIDGET(sheet_entry
), style
);
6218 text
= gtk_entry_get_text(GTK_ENTRY(sheet_entry
));
6219 if(text
&& strlen(text
) > 0){
6220 text_size
= STRING_WIDTH(GTK_WIDGET(sheet
), attributes
.font_desc
, text
);
6223 column_width
=sheet
->column
[sheet
->active_cell
.col
].width
;
6225 size
=MIN(text_size
, max_size
);
6226 size
=MAX(size
,column_width
-2*CELLOFFSET
);
6228 row
=sheet
->active_cell
.row
;
6229 col
=sheet
->active_cell
.col
;
6231 shentry_allocation
.x
= COLUMN_LEFT_XPIXEL(sheet
,sheet
->active_cell
.col
);
6232 shentry_allocation
.y
= ROW_TOP_YPIXEL(sheet
,sheet
->active_cell
.row
);
6233 shentry_allocation
.width
= column_width
;
6234 shentry_allocation
.height
= sheet
->row
[sheet
->active_cell
.row
].height
;
6236 shentry_allocation
.x
+= 2;
6237 shentry_allocation
.y
+= 2;
6238 shentry_allocation
.width
-= MIN(shentry_allocation
.width
, 3);
6239 shentry_allocation
.height
-= MIN(shentry_allocation
.height
, 3);
6241 gtk_widget_size_allocate(sheet
->sheet_entry
, &shentry_allocation
);
6243 if(previous_style
== style
) gtk_style_unref(previous_style
);
6248 create_sheet_entry(GtkSheet
*sheet
)
6254 gint found_entry
= FALSE
;
6256 widget
= GTK_WIDGET(sheet
);
6258 style
= gtk_style_copy(GTK_WIDGET(sheet
)->style
);
6260 if(sheet
->sheet_entry
){
6261 /* avoids warnings */
6262 gtk_widget_ref(sheet
->sheet_entry
);
6263 gtk_widget_unparent(sheet
->sheet_entry
);
6264 gtk_widget_destroy(sheet
->sheet_entry
);
6267 if(sheet
->entry_type
){
6269 if(!gtk_type_is_a (sheet
->entry_type
, GTK_TYPE_ENTRY
)){
6271 parent
= GTK_WIDGET(gtk_type_new(sheet
->entry_type
));
6273 sheet
->sheet_entry
= parent
;
6275 entry
= gtk_sheet_get_entry (sheet
);
6276 if(GTK_IS_ENTRY(entry
)) found_entry
= TRUE
;
6280 parent
= GTK_WIDGET(gtk_type_new(sheet
->entry_type
));
6288 g_warning ("Entry type must be GtkEntry subclass, using default");
6289 entry
= gtk_entry_new ();
6290 sheet
->sheet_entry
= entry
;
6294 sheet
->sheet_entry
= parent
;
6301 entry
= gtk_entry_new ();
6302 sheet
->sheet_entry
= entry
;
6306 gtk_widget_size_request(sheet
->sheet_entry
, NULL
);
6308 if(GTK_WIDGET_REALIZED(sheet
))
6310 gtk_widget_set_parent_window (sheet
->sheet_entry
, sheet
->sheet_window
);
6311 gtk_widget_set_parent(sheet
->sheet_entry
, GTK_WIDGET(sheet
));
6312 gtk_widget_realize(sheet
->sheet_entry
);
6316 /* SDB says: I need to work out the event passing system */
6317 gtk_signal_connect_object(GTK_OBJECT(entry
),"key_press_event",
6318 (GtkSignalFunc
) gtk_sheet_key_press
,
6320 /* gtk_signal_connect_object(GTK_OBJECT(entry),"key_press_event",
6321 (GtkSignalFunc) gtk_sheet_entry_key_press,
6326 gtk_widget_show (sheet
->sheet_entry
);
6331 gtk_sheet_get_entry(GtkSheet
*sheet
)
6334 GtkWidget
*entry
= NULL
;
6335 GtkTableChild
*table_child
;
6336 GtkBoxChild
*box_child
;
6337 GList
*children
= NULL
;
6339 g_return_val_if_fail (sheet
!= NULL
, NULL
);
6340 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
6341 g_return_val_if_fail (sheet
->sheet_entry
!= NULL
, NULL
);
6343 if(GTK_IS_ENTRY(sheet
->sheet_entry
)) return (sheet
->sheet_entry
);
6345 parent
= GTK_WIDGET(sheet
->sheet_entry
);
6347 if(GTK_IS_TABLE(parent
)) children
= GTK_TABLE(parent
)->children
;
6348 if(GTK_IS_BOX(parent
)) children
= GTK_BOX(parent
)->children
;
6350 if(!children
) return NULL
;
6353 if(GTK_IS_TABLE(parent
)) {
6354 table_child
= children
->data
;
6355 entry
= table_child
->widget
;
6357 if(GTK_IS_BOX(parent
)){
6358 box_child
= children
->data
;
6359 entry
= box_child
->widget
;
6362 if(GTK_IS_ENTRY(entry
))
6364 children
= g_list_next(children
);
6368 if(!GTK_IS_ENTRY(entry
)) return NULL
;
6375 gtk_sheet_get_entry_widget(GtkSheet
*sheet
)
6377 g_return_val_if_fail (sheet
!= NULL
, NULL
);
6378 g_return_val_if_fail (GTK_IS_SHEET (sheet
), NULL
);
6379 g_return_val_if_fail (sheet
->sheet_entry
!= NULL
, NULL
);
6381 return (sheet
->sheet_entry
);
6386 row_button_set (GtkSheet
*sheet
, gint row
)
6388 if(sheet
->row
[row
].button
.state
== GTK_STATE_ACTIVE
) return;
6390 sheet
->row
[row
].button
.state
= GTK_STATE_ACTIVE
;
6391 gtk_sheet_button_draw(sheet
, row
, -1);
6396 column_button_set (GtkSheet
*sheet
, gint column
)
6398 if(sheet
->column
[column
].button
.state
== GTK_STATE_ACTIVE
) return;
6400 sheet
->column
[column
].button
.state
= GTK_STATE_ACTIVE
;
6401 gtk_sheet_button_draw(sheet
, -1, column
);
6406 row_button_release (GtkSheet
*sheet
, gint row
)
6408 if(sheet
->row
[row
].button
.state
== GTK_STATE_NORMAL
) return;
6410 sheet
->row
[row
].button
.state
= GTK_STATE_NORMAL
;
6411 gtk_sheet_button_draw(sheet
, row
, -1);
6415 column_button_release (GtkSheet
*sheet
, gint column
)
6417 if(sheet
->column
[column
].button
.state
== GTK_STATE_NORMAL
) return;
6419 sheet
->column
[column
].button
.state
= GTK_STATE_NORMAL
;
6420 gtk_sheet_button_draw(sheet
, -1, column
);
6424 gtk_sheet_button_draw (GtkSheet
*sheet
, gint row
, gint column
)
6426 GdkWindow
*window
= NULL
;
6427 GtkShadowType shadow_type
;
6428 guint width
= 0, height
= 0;
6431 gint text_width
= 0, text_height
= 0;
6432 GtkSheetButton
*button
= NULL
;
6433 GtkSheetChild
*child
= NULL
;
6434 GdkRectangle allocation
;
6435 gboolean is_sensitive
= FALSE
;
6442 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))) return;
6444 if(row
>= 0 && !sheet
->row
[row
].is_visible
) return;
6445 if(column
>= 0 && !sheet
->column
[column
].is_visible
) return;
6446 if(row
>= 0 && !sheet
->row_titles_visible
) return;
6447 if(column
>= 0 && !sheet
->column_titles_visible
) return;
6448 if(column
>=0 && column
<MIN_VISIBLE_COLUMN(sheet
)) return;
6449 if(column
>=0 && column
>MAX_VISIBLE_COLUMN(sheet
)) return;
6450 if(row
>=0 && row
<MIN_VISIBLE_ROW(sheet
)) return;
6451 if(row
>=0 && row
>MAX_VISIBLE_ROW(sheet
)) return;
6452 if( (row
== -1) && (column
== -1) ) return;
6455 window
=sheet
->column_title_window
;
6456 button
=&sheet
->column
[column
].button
;
6458 x
= COLUMN_LEFT_XPIXEL(sheet
, column
)+CELL_SPACING
;
6459 if(sheet
->row_titles_visible
) x
-= sheet
->row_title_area
.width
;
6461 width
= sheet
->column
[column
].width
;
6462 height
= sheet
->column_title_area
.height
;
6463 is_sensitive
=sheet
->column
[column
].is_sensitive
;
6465 else if(column
==-1){
6466 window
=sheet
->row_title_window
;
6467 button
=&sheet
->row
[row
].button
;
6470 y
= ROW_TOP_YPIXEL(sheet
, row
)+CELL_SPACING
;
6471 if(sheet
->column_titles_visible
) y
-=sheet
->column_title_area
.height
;
6472 width
= sheet
->row_title_area
.width
;
6473 height
= sheet
->row
[row
].height
;
6474 is_sensitive
=sheet
->row
[row
].is_sensitive
;
6479 allocation
.width
= width
;
6480 allocation
.height
= height
;
6482 gdk_window_clear_area (window
,
6486 gtk_paint_box (sheet
->button
->style
, window
,
6487 GTK_STATE_NORMAL
, GTK_SHADOW_OUT
,
6488 &allocation
, GTK_WIDGET(sheet
),
6489 "buttondefault", x
, y
, width
, height
);
6491 state
= button
->state
;
6492 if(!is_sensitive
) state
=GTK_STATE_INSENSITIVE
;
6494 if (state
== GTK_STATE_ACTIVE
)
6495 shadow_type
= GTK_SHADOW_IN
;
6497 shadow_type
= GTK_SHADOW_OUT
;
6499 if(state
!= GTK_STATE_NORMAL
&& state
!= GTK_STATE_INSENSITIVE
)
6500 gtk_paint_box (sheet
->button
->style
, window
,
6501 button
->state
, shadow_type
,
6502 &allocation
, GTK_WIDGET(sheet
),
6503 "button", x
, y
, width
, height
);
6505 if(button
->label_visible
){
6507 text_height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))-2*CELLOFFSET
;
6509 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->fg_gc
[button
->state
],
6511 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->white_gc
, &allocation
);
6513 y
+= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
))/2 + sheet
->button
->style
->ythickness
+ DEFAULT_FONT_DESCENT(GTK_WIDGET(sheet
));
6515 if(button
->label
&& strlen(button
->label
)>0){
6517 words
=button
->label
;
6518 line
= g_new(gchar
, 1);
6521 while(words
&& *words
!= '\0'){
6524 line
=g_realloc(line
, len
+2);
6528 if(*words
== '\n' || *(words
+1) == '\0'){
6529 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, line
);
6531 switch(button
->justification
){
6532 case GTK_JUSTIFY_LEFT
:
6533 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6534 &allocation
, GTK_WIDGET(sheet
), "label",
6538 case GTK_JUSTIFY_RIGHT
:
6539 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6540 &allocation
, GTK_WIDGET(sheet
), "label",
6541 x
+ width
- text_width
- CELLOFFSET
, y
,
6544 case GTK_JUSTIFY_CENTER
:
6546 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6547 &allocation
, GTK_WIDGET(sheet
), "label",
6548 x
+ (width
- text_width
) /2, y
,
6552 y
+= text_height
+ 2;
6555 line
= g_new(gchar
, 1);
6562 sprintf(label
,"%d",index
);
6563 text_width
= STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, label
);
6565 switch(button
->justification
){
6566 case GTK_JUSTIFY_LEFT
:
6567 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6568 &allocation
, GTK_WIDGET(sheet
), "label",
6572 case GTK_JUSTIFY_RIGHT
:
6573 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6574 &allocation
, GTK_WIDGET(sheet
), "label",
6575 x
+ width
- text_width
- CELLOFFSET
, y
,
6578 case GTK_JUSTIFY_CENTER
:
6580 gtk_paint_string (GTK_WIDGET(sheet
)->style
, window
, state
,
6581 &allocation
, GTK_WIDGET(sheet
), "label",
6582 x
+ (width
- text_width
) /2, y
,
6588 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->fg_gc
[button
->state
],
6590 gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet
)->style
->white_gc
, NULL
);
6594 if((child
= button
->child
) && (child
->widget
)){
6595 child
->x
= allocation
.x
;
6596 child
->y
= allocation
.y
;
6598 child
->x
+= (width
- child
->widget
->requisition
.width
) / 2;
6599 child
->y
+= (height
- child
->widget
->requisition
.height
) / 2;
6600 allocation
.x
= child
->x
;
6601 allocation
.y
= child
->y
;
6602 allocation
.width
= child
->widget
->requisition
.width
;
6603 allocation
.height
= child
->widget
->requisition
.height
;
6608 gtk_widget_set_state(child
->widget
, button
->state
);
6610 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
6611 GTK_WIDGET_MAPPED(child
->widget
))
6613 gtk_widget_size_allocate(child
->widget
,
6615 gtk_widget_queue_draw(child
->widget
);
6626 * vadjustment_changed
6627 * hadjustment_changed
6628 * vadjustment_value_changed
6629 * hadjustment_value_changed */
6632 adjust_scrollbars (GtkSheet
* sheet
)
6635 if(sheet
->vadjustment
){
6636 sheet
->vadjustment
->page_size
= sheet
->sheet_window_height
;
6637 sheet
->vadjustment
->page_increment
= sheet
->sheet_window_height
/ 2;
6638 sheet
->vadjustment
->step_increment
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
6639 sheet
->vadjustment
->lower
= 0;
6640 sheet
->vadjustment
->upper
= SHEET_HEIGHT (sheet
) + 80;
6642 if (sheet->sheet_window_height - sheet->voffset > SHEET_HEIGHT (sheet))
6644 sheet->vadjustment->value = MAX(0, SHEET_HEIGHT (sheet) -
6645 sheet->sheet_window_height);
6646 gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment),
6650 gtk_signal_emit_by_name (GTK_OBJECT(sheet
->vadjustment
), "changed");
6654 if(sheet
->hadjustment
){
6655 sheet
->hadjustment
->page_size
= sheet
->sheet_window_width
;
6656 sheet
->hadjustment
->page_increment
= sheet
->sheet_window_width
/ 2;
6657 sheet
->hadjustment
->step_increment
= DEFAULT_COLUMN_WIDTH
;
6658 sheet
->hadjustment
->lower
= 0;
6659 sheet
->hadjustment
->upper
= SHEET_WIDTH (sheet
)+ 80;
6661 if (sheet->sheet_window_width - sheet->hoffset > SHEET_WIDTH (sheet))
6663 sheet->hadjustment->value = MAX(0, SHEET_WIDTH (sheet) -
6664 sheet->sheet_window_width);
6665 gtk_signal_emit_by_name (GTK_OBJECT(sheet->hadjustment),
6669 gtk_signal_emit_by_name (GTK_OBJECT(sheet
->hadjustment
), "changed");
6673 if(GTK_WIDGET_REALIZED(sheet))
6675 if(sheet->row_titles_visible){
6676 size_allocate_row_title_buttons(sheet);
6677 gdk_window_show(sheet->row_title_window);
6680 if(sheet->column_titles_visible){
6681 size_allocate_column_title_buttons(sheet);
6682 gdk_window_show(sheet->column_title_window);
6685 gtk_sheet_range_draw(sheet, NULL);
6692 vadjustment_changed (GtkAdjustment
* adjustment
,
6697 g_return_if_fail (adjustment
!= NULL
);
6698 g_return_if_fail (data
!= NULL
);
6700 sheet
= GTK_SHEET (data
);
6705 hadjustment_changed (GtkAdjustment
* adjustment
,
6710 g_return_if_fail (adjustment
!= NULL
);
6711 g_return_if_fail (data
!= NULL
);
6713 sheet
= GTK_SHEET (data
);
6719 vadjustment_value_changed (GtkAdjustment
* adjustment
,
6723 gint diff
, value
, old_value
;
6728 g_return_if_fail (adjustment
!= NULL
);
6729 g_return_if_fail (data
!= NULL
);
6730 g_return_if_fail (GTK_IS_SHEET (data
));
6732 sheet
= GTK_SHEET (data
);
6734 if(GTK_SHEET_IS_FROZEN(sheet
)) return;
6736 row
=ROW_FROM_YPIXEL(sheet
,sheet
->column_title_area
.height
+ CELL_SPACING
);
6737 if(!sheet
->column_titles_visible
)
6738 row
=ROW_FROM_YPIXEL(sheet
,CELL_SPACING
);
6740 old_value
= -sheet
->voffset
;
6742 for(i
=0; i
<= sheet
->maxrow
; i
++){
6743 if(sheet
->row
[i
].is_visible
) y
+=sheet
->row
[i
].height
;
6744 if(y
> adjustment
->value
) break;
6746 y
-=sheet
->row
[i
].height
;
6749 if (adjustment
->value
> sheet
->old_vadjustment
&& sheet
->old_vadjustment
> 0. &&
6750 sheet
->row
[i
].height
> sheet
->vadjustment
->step_increment
){
6751 /* This avoids embarrassing twitching */
6752 if(row
== new_row
&& row
!= sheet
->maxrow
&&
6753 adjustment
->value
- sheet
->old_vadjustment
>=
6754 sheet
->vadjustment
->step_increment
&&
6755 new_row
+ 1 != MIN_VISIBLE_ROW(sheet
)){
6757 y
=y
+sheet
->row
[row
].height
;
6761 /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
6762 if(sheet
->old_vadjustment
>= 0. && row
== new_row
){
6763 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
6767 sheet
->old_vadjustment
= sheet
->vadjustment
->value
;
6768 adjustment
->value
=y
;
6772 sheet
->vadjustment
->step_increment
=
6773 sheet
->row
[0].height
;
6775 sheet
->vadjustment
->step_increment
=
6776 MIN(sheet
->row
[new_row
].height
, sheet
->row
[new_row
-1].height
);
6779 sheet
->vadjustment
->value
=adjustment
->value
;
6781 value
= adjustment
->value
;
6783 if (value
>= -sheet
->voffset
)
6786 diff
= value
+ sheet
->voffset
;
6791 diff
= -sheet
->voffset
- value
;
6794 sheet
->voffset
= -value
;
6796 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, sheet
->column_title_area
.height
+1);
6797 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
6798 if(!sheet
->column_titles_visible
)
6799 sheet
->view
.row0
=ROW_FROM_YPIXEL(sheet
, 1);
6801 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
) &&
6802 sheet
->state
== GTK_SHEET_NORMAL
&&
6803 sheet
->active_cell
.row
>= 0 && sheet
->active_cell
.col
>= 0 &&
6804 !gtk_sheet_cell_isvisible(sheet
, sheet
->active_cell
.row
,
6805 sheet
->active_cell
.col
))
6809 text
= gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
6811 if(!text
|| strlen(text
)==0)
6812 gtk_sheet_cell_clear(sheet
,
6813 sheet
->active_cell
.row
,
6814 sheet
->active_cell
.col
);
6815 gtk_widget_unmap(sheet
->sheet_entry
);
6818 gtk_sheet_position_children(sheet
);
6820 gtk_sheet_range_draw(sheet
, NULL
);
6821 size_allocate_row_title_buttons(sheet
);
6822 size_allocate_global_button(sheet
);
6826 hadjustment_value_changed (GtkAdjustment
* adjustment
,
6830 gint i
, diff
, value
, old_value
;
6831 gint column
, new_column
;
6834 g_return_if_fail (adjustment
!= NULL
);
6835 g_return_if_fail (data
!= NULL
);
6836 g_return_if_fail (GTK_IS_SHEET (data
));
6838 sheet
= GTK_SHEET (data
);
6840 if(GTK_SHEET_IS_FROZEN(sheet
)) return;
6842 column
=COLUMN_FROM_XPIXEL(sheet
,sheet
->row_title_area
.width
+ CELL_SPACING
);
6843 if(!sheet
->row_titles_visible
)
6844 column
=COLUMN_FROM_XPIXEL(sheet
, CELL_SPACING
);
6846 old_value
= -sheet
->hoffset
;
6848 for(i
=0; i
<= sheet
->maxcol
; i
++){
6849 if(sheet
->column
[i
].is_visible
) x
+=sheet
->column
[i
].width
;
6850 if(x
> adjustment
->value
) break;
6852 x
-=sheet
->column
[i
].width
;
6855 if (adjustment
->value
> sheet
->old_hadjustment
&& sheet
->old_hadjustment
> 0 &&
6856 sheet
->column
[i
].width
> sheet
->hadjustment
->step_increment
){
6857 /* This avoids embarrassing twitching */
6858 if(column
== new_column
&& column
!= sheet
->maxcol
&&
6859 adjustment
->value
- sheet
->old_hadjustment
>=
6860 sheet
->hadjustment
->step_increment
&&
6861 new_column
+ 1 != MIN_VISIBLE_COLUMN(sheet
)){
6863 x
=x
+sheet
->column
[column
].width
;
6867 /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */
6868 if(sheet
->old_hadjustment
>= 0. && new_column
== column
){
6869 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
6873 sheet
->old_hadjustment
= sheet
->hadjustment
->value
;
6874 adjustment
->value
=x
;
6876 if(new_column
== 0){
6877 sheet
->hadjustment
->step_increment
=
6878 sheet
->column
[0].width
;
6880 sheet
->hadjustment
->step_increment
=
6881 MIN(sheet
->column
[new_column
].width
, sheet
->column
[new_column
-1].width
);
6885 sheet
->hadjustment
->value
=adjustment
->value
;
6887 value
= adjustment
->value
;
6889 if (value
>= -sheet
->hoffset
)
6892 diff
= value
+ sheet
->hoffset
;
6897 diff
= -sheet
->hoffset
- value
;
6900 sheet
->hoffset
= -value
;
6902 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, sheet
->row_title_area
.width
+1);
6903 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
6904 if(!sheet
->row_titles_visible
)
6905 sheet
->view
.col0
=COLUMN_FROM_XPIXEL(sheet
, 1);
6907 if(GTK_WIDGET_REALIZED(sheet
->sheet_entry
) &&
6908 sheet
->state
== GTK_SHEET_NORMAL
&&
6909 sheet
->active_cell
.row
>= 0 && sheet
->active_cell
.col
>= 0 &&
6910 !gtk_sheet_cell_isvisible(sheet
, sheet
->active_cell
.row
,
6911 sheet
->active_cell
.col
))
6915 text
= gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet
)));
6916 if(!text
|| strlen(text
)==0)
6917 gtk_sheet_cell_clear(sheet
,
6918 sheet
->active_cell
.row
,
6919 sheet
->active_cell
.col
);
6921 gtk_widget_unmap(sheet
->sheet_entry
);
6924 gtk_sheet_position_children(sheet
);
6926 gtk_sheet_range_draw(sheet
, NULL
);
6927 size_allocate_column_title_buttons(sheet
);
6931 /* COLUMN RESIZING */
6933 draw_xor_vline (GtkSheet
* sheet
)
6937 g_return_if_fail (sheet
!= NULL
);
6939 widget
= GTK_WIDGET (sheet
);
6941 gdk_draw_line (widget
->window
, sheet
->xor_gc
,
6943 sheet
->column_title_area
.height
,
6945 sheet
->sheet_window_height
+ 1);
6950 draw_xor_hline (GtkSheet
* sheet
)
6954 g_return_if_fail (sheet
!= NULL
);
6956 widget
= GTK_WIDGET (sheet
);
6958 gdk_draw_line (widget
->window
, sheet
->xor_gc
,
6959 sheet
->row_title_area
.width
,
6962 sheet
->sheet_window_width
+ 1,
6966 /* SELECTED RANGE */
6968 draw_xor_rectangle(GtkSheet
*sheet
, GtkSheetRange range
)
6971 GdkRectangle clip_area
, area
;
6974 area
.x
=COLUMN_LEFT_XPIXEL(sheet
, range
.col0
);
6975 area
.y
=ROW_TOP_YPIXEL(sheet
, range
.row0
);
6976 area
.width
=COLUMN_LEFT_XPIXEL(sheet
, range
.coli
)-area
.x
+
6977 sheet
->column
[range
.coli
].width
;
6978 area
.height
=ROW_TOP_YPIXEL(sheet
, range
.rowi
)-area
.y
+
6979 sheet
->row
[range
.rowi
].height
;
6981 clip_area
.x
=sheet
->row_title_area
.width
;
6982 clip_area
.y
=sheet
->column_title_area
.height
;
6983 clip_area
.width
=sheet
->sheet_window_width
;
6984 clip_area
.height
=sheet
->sheet_window_height
;
6986 if(!sheet
->row_titles_visible
) clip_area
.x
= 0;
6987 if(!sheet
->column_titles_visible
) clip_area
.y
= 0;
6990 area
.width
=area
.width
+area
.x
;
6993 if(area
.width
>clip_area
.width
) area
.width
=clip_area
.width
+10;
6995 area
.height
=area
.height
+area
.y
;
6998 if(area
.height
>clip_area
.height
) area
.height
=clip_area
.height
+10;
7003 clip_area
.height
+=3;
7005 gdk_gc_get_values(sheet
->xor_gc
, &values
);
7007 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, &clip_area
);
7010 gdk_draw_rectangle(sheet
->sheet_window
,
7014 area
.width
-2*i
, area
.height
-2*i
);
7017 gdk_gc_set_clip_rectangle(sheet
->xor_gc
, NULL
);
7019 gdk_gc_set_foreground(sheet
->xor_gc
, &values
.foreground
);
7024 /* this function returns the new width of the column being resized given
7025 * the column and x position of the cursor; the x cursor position is passed
7026 * in as a pointer and automaticaly corrected if it's beyond min/max limits */
7028 new_column_width (GtkSheet
* sheet
,
7033 GtkRequisition requisition
;
7037 requisition
.width
= sheet
->column
[column
].requisition
;
7039 /* you can't shrink a column to less than its minimum width */
7040 if (cx
< COLUMN_LEFT_XPIXEL (sheet
, column
) + requisition
.width
)
7042 *x
= cx
= COLUMN_LEFT_XPIXEL (sheet
, column
) + requisition
.width
;
7045 /* don't grow past the end of the window */
7047 if (cx > sheet->sheet_window_width)
7049 *x = cx = sheet->sheet_window_width;
7052 /* calculate new column width making sure it doesn't end up
7053 * less than the minimum width */
7054 width
= cx
- COLUMN_LEFT_XPIXEL (sheet
, column
);
7055 if (width
< requisition
.width
)
7056 width
= requisition
.width
;
7058 sheet
->column
[column
].width
= width
;
7059 gtk_sheet_recalc_left_xpixels(sheet
, column
+1);
7060 sheet
->view
.coli
=COLUMN_FROM_XPIXEL(sheet
, sheet
->sheet_window_width
);
7061 size_allocate_column_title_buttons (sheet
);
7066 /* this function returns the new height of the row being resized given
7067 * the row and y position of the cursor; the y cursor position is passed
7068 * in as a pointer and automaticaly corrected if it's beyond min/max limits */
7070 new_row_height (GtkSheet
* sheet
,
7074 GtkRequisition requisition
;
7079 requisition
.height
= sheet
->row
[row
].requisition
;
7081 /* you can't shrink a row to less than its minimum height */
7082 if (cy
< ROW_TOP_YPIXEL (sheet
, row
) + requisition
.height
)
7085 *y
= cy
= ROW_TOP_YPIXEL (sheet
, row
) + requisition
.height
;
7088 /* don't grow past the end of the window */
7090 if (cy > sheet->sheet_window_height)
7092 *y = cy = sheet->sheet_window_height;
7095 /* calculate new row height making sure it doesn't end up
7096 * less than the minimum height */
7097 height
= (cy
- ROW_TOP_YPIXEL (sheet
, row
));
7098 if (height
< requisition
.height
)
7099 height
= requisition
.height
;
7101 sheet
->row
[row
].height
= height
;
7102 gtk_sheet_recalc_top_ypixels(sheet
, row
);
7103 sheet
->view
.rowi
=ROW_FROM_YPIXEL(sheet
, sheet
->sheet_window_height
-1);
7104 size_allocate_row_title_buttons (sheet
);
7110 gtk_sheet_set_column_width (GtkSheet
* sheet
,
7116 g_return_if_fail (sheet
!= NULL
);
7117 g_return_if_fail (GTK_IS_SHEET (sheet
));
7119 if (column
< 0 || column
> sheet
->maxcol
)
7122 gtk_sheet_column_size_request(sheet
, column
, &min_width
);
7123 if(width
< min_width
) return;
7125 sheet
->column
[column
].width
= width
;
7127 gtk_sheet_recalc_left_xpixels(sheet
, column
+1);
7129 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) && !GTK_SHEET_IS_FROZEN(sheet
)){
7130 size_allocate_column_title_buttons (sheet
);
7131 adjust_scrollbars (sheet
);
7132 gtk_sheet_size_allocate_entry(sheet
);
7133 gtk_sheet_range_draw (sheet
, NULL
);
7136 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CHANGED
], -1, column
);
7137 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[NEW_COL_WIDTH
], column
, width
);
7142 gtk_sheet_set_row_height (GtkSheet
* sheet
,
7148 g_return_if_fail (sheet
!= NULL
);
7149 g_return_if_fail (GTK_IS_SHEET (sheet
));
7151 if (row
< 0 || row
> sheet
->maxrow
)
7154 gtk_sheet_row_size_request(sheet
, row
, &min_height
);
7155 if(height
< min_height
) return;
7157 sheet
->row
[row
].height
= height
;
7159 gtk_sheet_recalc_top_ypixels(sheet
, row
+1);
7161 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) && !GTK_SHEET_IS_FROZEN(sheet
)){
7162 size_allocate_row_title_buttons (sheet
);
7163 adjust_scrollbars (sheet
);
7164 gtk_sheet_size_allocate_entry(sheet
);
7165 gtk_sheet_range_draw (sheet
, NULL
);
7168 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[CHANGED
], row
, -1);
7169 gtk_signal_emit(GTK_OBJECT(sheet
), sheet_signals
[NEW_ROW_HEIGHT
], row
, height
);
7175 gtk_sheet_add_column(GtkSheet
*sheet
, guint ncols
)
7178 g_return_if_fail (sheet
!= NULL
);
7179 g_return_if_fail (GTK_IS_SHEET (sheet
));
7181 AddColumn(sheet
, ncols
);
7183 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7185 adjust_scrollbars(sheet
);
7187 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) sheet
->range
.coli
+=ncols
;
7189 sheet
->old_hadjustment
= -1.;
7190 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7191 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7196 gtk_sheet_add_row(GtkSheet
*sheet
, guint nrows
)
7199 g_return_if_fail (sheet
!= NULL
);
7200 g_return_if_fail (GTK_IS_SHEET (sheet
));
7202 AddRow(sheet
, nrows
);
7204 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7206 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) sheet
->range
.rowi
+=nrows
;
7208 adjust_scrollbars(sheet
);
7210 sheet
->old_vadjustment
= -1.;
7211 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7212 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7217 gtk_sheet_insert_rows(GtkSheet
*sheet
, guint row
, guint nrows
)
7220 GtkSheetChild
*child
;
7222 g_return_if_fail (sheet
!= NULL
);
7223 g_return_if_fail (GTK_IS_SHEET (sheet
));
7225 if(GTK_WIDGET_REALIZED(sheet
))
7226 gtk_sheet_real_unselect_range(sheet
, NULL
);
7228 InsertRow(sheet
, row
, nrows
);
7230 children
= sheet
->children
;
7233 child
= (GtkSheetChild
*)children
->data
;
7235 if(child
->attached_to_cell
)
7236 if(child
->row
>= row
) child
->row
+= nrows
;
7238 children
= g_list_next(children
);
7241 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7243 if(sheet
->state
==GTK_SHEET_COLUMN_SELECTED
) sheet
->range
.rowi
+=nrows
;
7244 adjust_scrollbars(sheet
);
7246 sheet
->old_vadjustment
= -1.;
7247 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7248 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7254 gtk_sheet_insert_columns(GtkSheet
*sheet
, guint col
, guint ncols
)
7257 GtkSheetChild
*child
;
7259 g_return_if_fail (sheet
!= NULL
);
7260 g_return_if_fail (GTK_IS_SHEET (sheet
));
7262 if(GTK_WIDGET_REALIZED(sheet
))
7263 gtk_sheet_real_unselect_range(sheet
, NULL
);
7265 InsertColumn(sheet
, col
, ncols
);
7267 children
= sheet
->children
;
7270 child
= (GtkSheetChild
*)children
->data
;
7272 if(child
->attached_to_cell
)
7273 if(child
->col
>= col
) child
->col
+= ncols
;
7275 children
= g_list_next(children
);
7278 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7280 if(sheet
->state
==GTK_SHEET_ROW_SELECTED
) sheet
->range
.coli
+=ncols
;
7281 adjust_scrollbars(sheet
);
7283 sheet
->old_hadjustment
= -1.;
7284 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7285 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7291 gtk_sheet_delete_rows(GtkSheet
*sheet
, guint row
, guint nrows
)
7294 GtkSheetChild
*child
;
7298 g_return_if_fail (sheet
!= NULL
);
7299 g_return_if_fail (GTK_IS_SHEET (sheet
));
7301 nrows
= MIN(nrows
, sheet
->maxrow
-row
+1);
7303 if(GTK_WIDGET_REALIZED(sheet
))
7304 gtk_sheet_real_unselect_range(sheet
, NULL
);
7306 DeleteRow(sheet
, row
, nrows
);
7308 children
= sheet
->children
;
7311 child
= (GtkSheetChild
*)children
->data
;
7313 if(child
->attached_to_cell
&&
7314 child
->row
>= row
&& child
->row
< row
+nrows
){
7315 gtk_container_remove(GTK_CONTAINER(sheet
), child
->widget
);
7316 children
= sheet
->children
;
7318 children
= g_list_next(children
);
7321 children
= sheet
->children
;
7324 child
= (GtkSheetChild
*)children
->data
;
7326 if(child
->attached_to_cell
&& child
->row
> row
) child
->row
-= nrows
;
7327 children
= g_list_next(children
);
7330 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7332 irow
= sheet
->active_cell
.row
;
7333 icol
= sheet
->active_cell
.col
;
7335 sheet
->active_cell
.row
= -1;
7336 sheet
->active_cell
.col
= -1;
7338 /* if(sheet->state == GTK_SHEET_ROW_SELECTED)
7341 irow
= MIN(irow
, sheet
->maxrow
);
7342 irow
= MAX(irow
, 0);
7343 gtk_sheet_click_cell(sheet
, irow
, icol
, &veto
);
7345 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
7346 sheet
->active_cell
.col
);
7348 adjust_scrollbars(sheet
);
7350 sheet
->old_vadjustment
= -1.;
7351 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->vadjustment
)
7352 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->vadjustment
),
7358 gtk_sheet_delete_columns(GtkSheet
*sheet
, guint col
, guint ncols
)
7361 GtkSheetChild
*child
;
7365 g_return_if_fail (sheet
!= NULL
);
7366 g_return_if_fail (GTK_IS_SHEET (sheet
));
7368 ncols
= MIN(ncols
, sheet
->maxcol
-col
+1);
7370 if(GTK_WIDGET_REALIZED(sheet
))
7371 gtk_sheet_real_unselect_range(sheet
, NULL
);
7373 DeleteColumn(sheet
, col
, ncols
);
7375 children
= sheet
->children
;
7378 child
= (GtkSheetChild
*)children
->data
;
7380 if(child
->attached_to_cell
&&
7381 child
->col
>= col
&& child
->col
< col
+ncols
){
7382 gtk_container_remove(GTK_CONTAINER(sheet
), child
->widget
);
7383 children
= sheet
->children
;
7385 children
= g_list_next(children
);
7388 children
= sheet
->children
;
7391 child
= (GtkSheetChild
*)children
->data
;
7393 if(child
->attached_to_cell
&& child
->col
> col
) child
->col
-= ncols
;
7394 children
= g_list_next(children
);
7397 if(!GTK_WIDGET_REALIZED(sheet
)) return;
7399 irow
= sheet
->active_cell
.row
;
7400 icol
= sheet
->active_cell
.col
;
7402 sheet
->active_cell
.row
= -1;
7403 sheet
->active_cell
.col
= -1;
7405 /* if(sheet->state == GTK_SHEET_COLUMN_SELECTED)
7408 icol
= MIN(icol
, sheet
->maxcol
);
7409 icol
= MAX(icol
, 0);
7410 gtk_sheet_click_cell(sheet
, irow
, icol
, &veto
);
7412 gtk_sheet_activate_cell(sheet
, sheet
->active_cell
.row
,
7413 sheet
->active_cell
.col
);
7415 adjust_scrollbars(sheet
);
7417 sheet
->old_hadjustment
= -1.;
7418 if(!GTK_SHEET_IS_FROZEN(sheet
) && sheet
->hadjustment
)
7419 gtk_signal_emit_by_name (GTK_OBJECT (sheet
->hadjustment
),
7425 gtk_sheet_range_set_background(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7428 GtkSheetCellAttr attributes
;
7429 GtkSheetRange range
;
7431 g_return_if_fail (sheet
!= NULL
);
7432 g_return_if_fail (GTK_IS_SHEET (sheet
));
7435 range
= sheet
->range
;
7439 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7440 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7441 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7443 attributes
.background
= *color
;
7445 attributes
.background
= sheet
->bg_color
;
7447 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7455 if(!GTK_SHEET_IS_FROZEN(sheet
))
7456 gtk_sheet_range_draw(sheet
, &range
);
7461 gtk_sheet_range_set_foreground(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7464 GtkSheetCellAttr attributes
;
7465 GtkSheetRange range
;
7467 g_return_if_fail (sheet
!= NULL
);
7468 g_return_if_fail (GTK_IS_SHEET (sheet
));
7471 range
= sheet
->range
;
7475 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7476 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7477 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7480 attributes
.foreground
= *color
;
7482 gdk_color_black(gdk_colormap_get_system(), &attributes
.foreground
);
7484 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7487 if(!GTK_SHEET_IS_FROZEN(sheet
))
7488 gtk_sheet_range_draw(sheet
, &range
);
7493 gtk_sheet_range_set_justification(GtkSheet
*sheet
, const GtkSheetRange
*urange
,
7494 GtkJustification just
)
7497 GtkSheetCellAttr attributes
;
7498 GtkSheetRange range
;
7500 g_return_if_fail (sheet
!= NULL
);
7501 g_return_if_fail (GTK_IS_SHEET (sheet
));
7504 range
= sheet
->range
;
7508 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7509 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7510 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7511 attributes
.justification
= just
;
7512 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7515 range
.col0
= sheet
->view
.col0
;
7516 range
.coli
= sheet
->view
.coli
;
7518 if(!GTK_SHEET_IS_FROZEN(sheet
))
7519 gtk_sheet_range_draw(sheet
, &range
);
7524 gtk_sheet_column_set_justification(GtkSheet
*sheet
, gint col
,
7525 GtkJustification justification
)
7527 g_return_if_fail (sheet
!= NULL
);
7528 g_return_if_fail (GTK_IS_SHEET (sheet
));
7530 if(col
> sheet
->maxcol
) return;
7532 sheet
->column
[col
].justification
= justification
;
7534 if(GTK_WIDGET_REALIZED(sheet
) && !GTK_SHEET_IS_FROZEN(sheet
) &&
7535 col
>= MIN_VISIBLE_COLUMN(sheet
) && col
<= MAX_VISIBLE_COLUMN(sheet
))
7536 gtk_sheet_range_draw(sheet
, NULL
);
7541 gtk_sheet_range_set_editable(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gboolean editable
)
7544 GtkSheetCellAttr attributes
;
7545 GtkSheetRange range
;
7547 g_return_if_fail (sheet
!= NULL
);
7548 g_return_if_fail (GTK_IS_SHEET (sheet
));
7551 range
= sheet
->range
;
7555 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7556 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7557 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7558 attributes
.is_editable
= editable
;
7559 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7562 if(!GTK_SHEET_IS_FROZEN(sheet
))
7563 gtk_sheet_range_draw(sheet
, &range
);
7568 gtk_sheet_range_set_visible(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gboolean visible
)
7571 GtkSheetCellAttr attributes
;
7572 GtkSheetRange range
;
7574 g_return_if_fail (sheet
!= NULL
);
7575 g_return_if_fail (GTK_IS_SHEET (sheet
));
7578 range
= sheet
->range
;
7582 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7583 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7584 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7585 attributes
.is_visible
=visible
;
7586 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7589 if(!GTK_SHEET_IS_FROZEN(sheet
))
7590 gtk_sheet_range_draw(sheet
, &range
);
7595 gtk_sheet_range_set_border(GtkSheet
*sheet
, const GtkSheetRange
*urange
, gint mask
,
7596 guint width
, gint line_style
)
7599 GtkSheetCellAttr attributes
;
7600 GtkSheetRange range
;
7602 g_return_if_fail (sheet
!= NULL
);
7603 g_return_if_fail (GTK_IS_SHEET (sheet
));
7606 range
= sheet
->range
;
7610 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7611 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7612 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7613 attributes
.border
.mask
= mask
;
7614 attributes
.border
.width
= width
;
7615 attributes
.border
.line_style
=line_style
;
7616 attributes
.border
.cap_style
=GDK_CAP_NOT_LAST
;
7617 attributes
.border
.join_style
=GDK_JOIN_MITER
;
7618 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7626 if(!GTK_SHEET_IS_FROZEN(sheet
))
7627 gtk_sheet_range_draw(sheet
, &range
);
7632 gtk_sheet_range_set_border_color(GtkSheet
*sheet
, const GtkSheetRange
*urange
, const GdkColor
*color
)
7635 GtkSheetCellAttr attributes
;
7636 GtkSheetRange range
;
7638 g_return_if_fail (sheet
!= NULL
);
7639 g_return_if_fail (GTK_IS_SHEET (sheet
));
7642 range
= sheet
->range
;
7646 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7647 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7648 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7649 attributes
.border
.color
= *color
;
7650 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7653 if(!GTK_SHEET_IS_FROZEN(sheet
))
7654 gtk_sheet_range_draw(sheet
, &range
);
7659 gtk_sheet_range_set_font(GtkSheet
*sheet
, const GtkSheetRange
*urange
, PangoFontDescription
*font
)
7663 GtkSheetCellAttr attributes
;
7664 GtkSheetRange range
;
7665 PangoContext
*context
;
7666 PangoFontMetrics
*metrics
;
7668 g_return_if_fail (sheet
!= NULL
);
7669 g_return_if_fail (GTK_IS_SHEET (sheet
));
7672 range
= sheet
->range
;
7676 gtk_sheet_freeze(sheet
);
7678 context
= gtk_widget_get_pango_context(GTK_WIDGET(sheet
));
7679 metrics
= pango_context_get_metrics(context
,
7681 pango_context_get_language(context
));
7682 font_height
= pango_font_metrics_get_descent(metrics
) +
7683 pango_font_metrics_get_ascent(metrics
);
7684 font_height
= PANGO_PIXELS(font_height
) + 2*CELLOFFSET
;
7686 for (i
=range
.row0
; i
<=range
.rowi
; i
++)
7687 for (j
=range
.col0
; j
<=range
.coli
; j
++){
7688 gtk_sheet_get_attributes(sheet
, i
, j
, &attributes
);
7689 attributes
.font_desc
= font
;
7690 if(font_height
> sheet
->row
[i
].height
){
7691 sheet
->row
[i
].height
= font_height
;
7692 gtk_sheet_recalc_top_ypixels(sheet
, i
);
7695 gtk_sheet_set_cell_attributes(sheet
, i
, j
, attributes
);
7698 gtk_sheet_thaw(sheet
);
7699 pango_font_metrics_unref(metrics
);
7703 gtk_sheet_set_cell_attributes(GtkSheet
*sheet
, gint row
, gint col
, GtkSheetCellAttr attributes
)
7705 GtkSheetCell
**cell
;
7707 if(row
> sheet
->maxrow
|| col
>sheet
->maxcol
) return;
7709 CheckBounds(sheet
, row
, col
);
7711 cell
= &sheet
->data
[row
][col
];
7714 (*cell
) = gtk_sheet_cell_new();
7719 if((*cell
)->attributes
== NULL
)
7720 (*cell
)->attributes
= g_new(GtkSheetCellAttr
, 1);
7722 *((*cell
)->attributes
) = attributes
;
7726 gtk_sheet_get_attributes(GtkSheet
*sheet
, gint row
, gint col
, GtkSheetCellAttr
*attributes
)
7728 GtkSheetCell
**cell
= NULL
;
7730 g_return_val_if_fail (sheet
!= NULL
, FALSE
);
7731 g_return_val_if_fail (GTK_IS_SHEET (sheet
), FALSE
);
7733 if(row
< 0 || col
< 0) return FALSE
;
7735 if(row
> sheet
->maxallocrow
|| col
> sheet
->maxalloccol
){
7736 init_attributes(sheet
, col
, attributes
);
7740 if(row
<= sheet
->maxallocrow
&& col
<= sheet
->maxalloccol
){
7741 if(sheet
->data
[row
] && sheet
->data
[row
][col
])
7742 cell
= &sheet
->data
[row
][col
];
7743 if(cell
== NULL
|| *cell
== NULL
){
7744 init_attributes(sheet
, col
, attributes
);
7747 if((*cell
)->attributes
== NULL
){
7748 init_attributes(sheet
, col
, attributes
);
7751 *attributes
= *(sheet
->data
[row
][col
]->attributes
);
7752 if(sheet
->column
[col
].justification
!= GTK_JUSTIFY_FILL
)
7753 attributes
->justification
= sheet
->column
[col
].justification
;
7761 init_attributes(GtkSheet
*sheet
, gint col
, GtkSheetCellAttr
*attributes
)
7763 /* DEFAULT VALUES */
7764 attributes
->foreground
= GTK_WIDGET(sheet
)->style
->black
;
7765 attributes
->background
= sheet
->bg_color
;
7766 if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
))){
7767 GdkColormap
*colormap
;
7768 colormap
=gdk_colormap_get_system();
7769 gdk_color_black(colormap
, &attributes
->foreground
);
7770 attributes
->background
= sheet
->bg_color
;
7772 attributes
->justification
= sheet
->column
[col
].justification
;
7773 attributes
->border
.width
= 0;
7774 attributes
->border
.line_style
= GDK_LINE_SOLID
;
7775 attributes
->border
.cap_style
= GDK_CAP_NOT_LAST
;
7776 attributes
->border
.join_style
= GDK_JOIN_MITER
;
7777 attributes
->border
.mask
= 0;
7778 attributes
->border
.color
= GTK_WIDGET(sheet
)->style
->black
;
7779 attributes
->is_editable
= TRUE
;
7780 attributes
->is_visible
= TRUE
;
7781 attributes
->font
= GTK_WIDGET(sheet
)->style
->private_font
;
7782 attributes
->font_desc
= GTK_WIDGET(sheet
)->style
->font_desc
;
7786 /**********************************************************************
7787 * Memory allocation routines:
7788 * AddRow & AddColumn allocate memory for GtkSheetColumn & GtkSheetRow structs.
7793 * GrowSheet allocates memory for the sheet cells contents using an array of
7794 * pointers. Alternative to this could be a linked list or a hash table.
7795 * CheckBounds checks whether the given cell is currently allocated or not.
7796 * If not, it calls to GrowSheet.
7797 **********************************************************************/
7800 AddColumn(GtkSheet
*tbl
, gint ncols
)
7804 if(ncols
== -1 && tbl
->maxcol
== 0)
7810 tbl
->maxcol
+= ncols
;
7811 tbl
->column
= (GtkSheetColumn
*)g_realloc(tbl
->column
,(tbl
->maxcol
+1)*
7812 sizeof(GtkSheetColumn
));
7815 for(i
=tbl
->maxcol
-ncols
+1; i
<= tbl
->maxcol
; i
++){
7816 tbl
->column
[i
].width
=DEFAULT_COLUMN_WIDTH
;
7817 tbl
->column
[i
].button
.label
=NULL
;
7818 tbl
->column
[i
].button
.child
=NULL
;
7819 tbl
->column
[i
].button
.state
=GTK_STATE_NORMAL
;
7820 tbl
->column
[i
].button
.justification
=GTK_JUSTIFY_CENTER
;
7821 tbl
->column
[i
].button
.label_visible
= TRUE
;
7822 tbl
->column
[i
].name
=NULL
;
7823 tbl
->column
[i
].is_visible
=TRUE
;
7824 tbl
->column
[i
].is_sensitive
=TRUE
;
7825 tbl
->column
[i
].left_text_column
=i
;
7826 tbl
->column
[i
].right_text_column
=i
;
7827 tbl
->column
[i
].justification
=GTK_JUSTIFY_FILL
;
7828 tbl
->column
[i
].requisition
=DEFAULT_COLUMN_WIDTH
;
7831 tbl
->column
[i
].left_text_column
=tbl
->column
[i
-1].left_text_column
;
7832 tbl
->column
[i
].left_xpixel
=tbl
->column
[i
-1].left_xpixel
+
7833 tbl
->column
[i
-1].width
;
7837 tbl
->column
[i
].left_xpixel
=tbl
->row_title_area
.width
;
7838 if(!tbl
->row_titles_visible
)
7839 tbl
->column
[i
].left_xpixel
=0;
7846 AddRow(GtkSheet
*tbl
, gint nrows
)
7850 if(nrows
== -1 && tbl
->maxrow
== 0)
7856 tbl
->maxrow
+= nrows
;
7857 tbl
->row
= (GtkSheetRow
*)g_realloc(tbl
->row
,(tbl
->maxrow
+1)*
7858 sizeof(GtkSheetRow
));
7861 for(i
=tbl
->maxrow
-nrows
+1; i
<= tbl
->maxrow
; i
++){
7862 tbl
->row
[i
].requisition
=tbl
->row
[i
].height
=DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl
));
7863 tbl
->row
[i
].button
.label
=NULL
;
7864 tbl
->row
[i
].button
.child
=NULL
;
7865 tbl
->row
[i
].button
.state
=GTK_STATE_NORMAL
;
7866 tbl
->row
[i
].button
.justification
=GTK_JUSTIFY_CENTER
;
7867 tbl
->row
[i
].button
.label_visible
= TRUE
;
7868 tbl
->row
[i
].name
=NULL
;
7869 tbl
->row
[i
].is_visible
=TRUE
;
7870 tbl
->row
[i
].is_sensitive
=TRUE
;
7872 tbl
->row
[i
].top_ypixel
=tbl
->row
[i
-1].top_ypixel
+tbl
->row
[i
-1].height
;
7875 tbl
->row
[i
].top_ypixel
=tbl
->column_title_area
.height
;
7876 if(!tbl
->column_titles_visible
)
7877 tbl
->row
[i
].top_ypixel
=0;
7884 InsertRow(GtkSheet
*tbl
, gint row
, gint nrows
)
7888 GtkSheetCell
**auxdata
;
7893 for(i
=tbl
->maxrow
; i
>=row
+nrows
; i
--){
7894 auxrow
= tbl
->row
[i
];
7895 tbl
->row
[i
]=tbl
->row
[i
-nrows
];
7896 tbl
->row
[i
].is_visible
=tbl
->row
[i
-nrows
].is_visible
;
7897 tbl
->row
[i
].is_sensitive
=tbl
->row
[i
-nrows
].is_sensitive
;
7898 if(auxrow
.is_visible
)
7899 tbl
->row
[i
].top_ypixel
+=nrows
*DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl
));
7900 tbl
->row
[i
-nrows
]=auxrow
;
7903 if(row
<= tbl
->maxallocrow
){
7905 GrowSheet(tbl
,nrows
,0);
7907 for(i
=tbl
->maxallocrow
; i
>=row
+nrows
; i
--){
7908 auxdata
= tbl
->data
[i
];
7909 tbl
->data
[i
]=tbl
->data
[i
-nrows
];
7912 for(j
=0; j
<=tbl
->maxalloccol
; j
++,pp
++){
7913 if(*pp
!=(GtkSheetCell
*)NULL
)
7917 tbl
->data
[i
-nrows
]=auxdata
;
7920 gtk_sheet_recalc_top_ypixels(tbl
, 0);
7925 InsertColumn(GtkSheet
*tbl
, gint col
, gint ncols
)
7928 GtkSheetColumn auxcol
;
7930 AddColumn(tbl
,ncols
);
7932 for(i
=tbl
->maxcol
; i
>=col
+ncols
; i
--){
7933 auxcol
= tbl
->column
[i
];
7934 tbl
->column
[i
]=tbl
->column
[i
-ncols
];
7935 tbl
->column
[i
].is_visible
=tbl
->column
[i
-ncols
].is_visible
;
7936 tbl
->column
[i
].is_sensitive
=tbl
->column
[i
-ncols
].is_sensitive
;
7937 tbl
->column
[i
].left_text_column
=tbl
->column
[i
-ncols
].left_text_column
;
7938 tbl
->column
[i
].right_text_column
=tbl
->column
[i
-ncols
].right_text_column
;
7939 tbl
->column
[i
].justification
=tbl
->column
[i
-ncols
].justification
;
7940 if(auxcol
.is_visible
) tbl
->column
[i
].left_xpixel
+=ncols
*DEFAULT_COLUMN_WIDTH
;
7941 tbl
->column
[i
-ncols
]=auxcol
;
7944 if(col
<= tbl
->maxalloccol
){
7946 GrowSheet(tbl
,0,ncols
);
7948 for(i
=0; i
<=tbl
->maxallocrow
; i
++){
7949 for(j
=tbl
->maxalloccol
; j
>=col
+ncols
; j
--){
7950 gtk_sheet_real_cell_clear(tbl
, i
, j
, TRUE
);
7951 tbl
->data
[i
][j
]=tbl
->data
[i
][j
-ncols
];
7952 if(tbl
->data
[i
][j
]) tbl
->data
[i
][j
]->col
=j
;
7953 tbl
->data
[i
][j
-ncols
]=NULL
;
7957 gtk_sheet_recalc_left_xpixels(tbl
, 0);
7962 DeleteRow(GtkSheet
*tbl
, gint row
, gint nrows
)
7964 GtkSheetCell
**auxdata
= NULL
;
7967 if(nrows
<= 0 || row
> tbl
->maxrow
) return TRUE
;
7969 nrows
=MIN(nrows
,tbl
->maxrow
-row
+1);
7971 for(i
=row
; i
<row
+nrows
; i
++){
7972 if(tbl
->row
[i
].name
){
7973 g_free(tbl
->row
[i
].name
);
7974 tbl
->row
[i
].name
= NULL
;
7976 if(tbl
->row
[i
].button
.label
){
7977 g_free(tbl
->row
[i
].button
.label
);
7978 tbl
->row
[i
].button
.label
= NULL
;
7982 for(i
=row
; i
<=tbl
->maxrow
-nrows
; i
++){
7983 if(i
+nrows
<= tbl
->maxrow
){
7984 tbl
->row
[i
]=tbl
->row
[i
+nrows
];
7988 if(row
<= tbl
->maxallocrow
){
7990 for(i
=row
; i
<=tbl
->maxrow
-nrows
; i
++){
7991 if(i
<=tbl
->maxallocrow
){
7992 auxdata
=tbl
->data
[i
];
7993 for(j
=0; j
<=tbl
->maxalloccol
; j
++){
7994 gtk_sheet_real_cell_clear(tbl
, i
, j
, TRUE
);
7997 if(i
+nrows
<=tbl
->maxallocrow
){
7998 tbl
->data
[i
]=tbl
->data
[i
+nrows
];
7999 tbl
->data
[i
+nrows
]=auxdata
;
8000 for(j
=0; j
<=tbl
->maxalloccol
; j
++){
8001 if(tbl
->data
[i
][j
]) tbl
->data
[i
][j
]->row
=i
;
8006 for(i
=tbl
->maxrow
-nrows
+1; i
<=tbl
->maxallocrow
; i
++){
8007 if(i
> 0 && tbl
->data
[i
]){
8008 g_free(tbl
->data
[i
]);
8009 tbl
->data
[i
] = NULL
;
8013 tbl
->maxallocrow
-=MIN(nrows
,tbl
->maxallocrow
-row
+1);
8014 tbl
->maxallocrow
= MIN(tbl
->maxallocrow
, tbl
->maxrow
);
8019 gtk_sheet_recalc_top_ypixels(tbl
, 0);
8024 DeleteColumn(GtkSheet
*tbl
, gint column
, gint ncols
)
8027 GtkSheetColumn auxcol
;
8029 ncols
= MIN(ncols
,tbl
->maxcol
-column
+1);
8031 if(ncols
<= 0 || column
> tbl
->maxcol
) return TRUE
;
8033 for(i
=column
; i
<column
+ncols
; i
++){
8034 auxcol
=tbl
->column
[i
];
8035 if(tbl
->column
[i
].name
){
8036 g_free(tbl
->column
[i
].name
);
8037 tbl
->column
[i
].name
= NULL
;
8039 if(tbl
->column
[i
].button
.label
){
8040 g_free(tbl
->column
[i
].button
.label
);
8041 tbl
->column
[i
].button
.label
= NULL
;
8045 for(i
=column
; i
<=tbl
->maxcol
-ncols
; i
++){
8046 if(i
+ncols
<= tbl
->maxcol
){
8047 tbl
->column
[i
]=tbl
->column
[i
+ncols
];
8051 if(column
<= tbl
->maxalloccol
){
8053 for(i
=column
; i
<=tbl
->maxcol
-ncols
; i
++){
8054 if(i
<=tbl
->maxalloccol
){
8055 for(j
=0; j
<=tbl
->maxallocrow
; j
++){
8056 gtk_sheet_real_cell_clear(tbl
, j
, i
, TRUE
);
8057 if(i
+ncols
<= tbl
->maxalloccol
){
8058 tbl
->data
[j
][i
] = tbl
->data
[j
][i
+ncols
];
8059 tbl
->data
[j
][i
+ncols
] = NULL
;
8060 if(tbl
->data
[j
][i
]) tbl
->data
[j
][i
]->col
=i
;
8067 tbl
->maxalloccol
-=MIN(ncols
,tbl
->maxalloccol
-column
+1);
8068 tbl
->maxalloccol
= MIN(tbl
->maxalloccol
, tbl
->maxcol
);
8071 gtk_sheet_recalc_left_xpixels(tbl
, 0);
8076 GrowSheet(GtkSheet
*tbl
, gint newrows
, gint newcols
)
8079 gint inirow
, inicol
;
8081 inirow
= tbl
->maxallocrow
+ 1;
8082 inicol
= tbl
->maxalloccol
+ 1;
8084 tbl
->maxalloccol
= tbl
->maxalloccol
+ newcols
;
8085 tbl
->maxallocrow
= tbl
->maxallocrow
+ newrows
;
8088 tbl
->data
= (GtkSheetCell
***)
8089 g_realloc(tbl
->data
,(tbl
->maxallocrow
+1)*sizeof(GtkSheetCell
**)+sizeof(double));
8091 for(i
=inirow
; i
<= tbl
->maxallocrow
; i
++){
8092 tbl
->data
[i
] = (GtkSheetCell
**) \
8093 g_malloc((tbl
->maxcol
+1)*sizeof(GtkSheetCell
*)+sizeof(double));
8094 for(j
=0; j
<inicol
; j
++) {
8095 tbl
->data
[i
][j
] = NULL
;
8102 for(i
=0; i
<= tbl
->maxallocrow
; i
++) {
8103 tbl
->data
[i
] = (GtkSheetCell
**) \
8104 g_realloc(tbl
->data
[i
],(tbl
->maxalloccol
+1)*sizeof(GtkSheetCell
*)+sizeof(double));
8105 for(j
=inicol
; j
<= tbl
->maxalloccol
; j
++) {
8106 tbl
->data
[i
][j
] = NULL
;
8115 CheckBounds(GtkSheet
*tbl
, gint row
, gint col
)
8117 gint newrows
=0,newcols
=0;
8119 if(col
>tbl
->maxalloccol
) newcols
=col
-tbl
->maxalloccol
;
8120 if(row
>tbl
->maxallocrow
) newrows
=row
-tbl
->maxallocrow
;
8121 if(newrows
>0 || newcols
>0) GrowSheet(tbl
, newrows
, newcols
);
8125 /********************************************************************
8126 * Container Functions:
8131 * gtk_sheet_move_child
8132 * gtk_sheet_position_child
8133 * gtk_sheet_position_children
8134 * gtk_sheet_realize_child
8135 * gtk_sheet_get_child_at
8136 ********************************************************************/
8139 gtk_sheet_put(GtkSheet
*sheet
, GtkWidget
*child
, gint x
, gint y
)
8141 GtkRequisition child_requisition
;
8142 GtkSheetChild
*child_info
;
8144 g_return_val_if_fail(sheet
!= NULL
, NULL
);
8145 g_return_val_if_fail(GTK_IS_SHEET(sheet
), NULL
);
8146 g_return_val_if_fail(child
!= NULL
, NULL
);
8147 g_return_val_if_fail(child
->parent
== NULL
, NULL
);
8149 child_info
= g_new (GtkSheetChild
, 1);
8150 child_info
->widget
= child
;
8153 child_info
->attached_to_cell
= FALSE
;
8154 child_info
->floating
= TRUE
;
8155 child_info
->xpadding
= child_info
->ypadding
= 0;
8156 child_info
->xexpand
= child_info
->yexpand
= FALSE
;
8157 child_info
->xshrink
= child_info
->yshrink
= FALSE
;
8158 child_info
->xfill
= child_info
->yfill
= FALSE
;
8160 sheet
->children
= g_list_append(sheet
->children
, child_info
);
8162 gtk_widget_set_parent (child
, GTK_WIDGET(sheet
));
8164 gtk_widget_size_request(child
, &child_requisition
);
8166 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8168 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8169 (!GTK_WIDGET_REALIZED(child
) || GTK_WIDGET_NO_WINDOW(child
)))
8170 gtk_sheet_realize_child(sheet
, child_info
);
8172 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8173 !GTK_WIDGET_MAPPED(child
))
8174 gtk_widget_map(child
);
8177 gtk_sheet_position_child(sheet
, child_info
);
8179 /* This will avoid drawing on the titles */
8181 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)))
8183 if(sheet
->row_titles_visible
)
8184 gdk_window_show(sheet
->row_title_window
);
8185 if(sheet
->column_titles_visible
)
8186 gdk_window_show(sheet
->column_title_window
);
8189 return (child_info
);
8193 gtk_sheet_attach_floating (GtkSheet
*sheet
,
8198 GtkSheetChild
*child
;
8200 if(row
< 0 || col
< 0){
8201 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8205 gtk_sheet_get_cell_area(sheet
, row
, col
, &area
);
8206 child
= gtk_sheet_put(sheet
, widget
, area
.x
, area
.y
);
8207 child
->attached_to_cell
= TRUE
;
8213 gtk_sheet_attach_default (GtkSheet
*sheet
,
8217 if(row
< 0 || col
< 0){
8218 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8222 gtk_sheet_attach(sheet
, widget
, row
, col
, GTK_EXPAND
|GTK_FILL
, GTK_EXPAND
|GTK_FILL
, 0, 0);
8226 gtk_sheet_attach (GtkSheet
*sheet
,
8235 GtkSheetChild
*child
= NULL
;
8237 if(row
< 0 || col
< 0){
8238 gtk_sheet_button_attach(sheet
, widget
, row
, col
);
8242 child
= g_new0(GtkSheetChild
, 1);
8243 child
->attached_to_cell
= TRUE
;
8244 child
->floating
= FALSE
;
8245 child
->widget
= widget
;
8248 child
->xpadding
= xpadding
;
8249 child
->ypadding
= ypadding
;
8250 child
->xexpand
= (xoptions
& GTK_EXPAND
) != 0;
8251 child
->yexpand
= (yoptions
& GTK_EXPAND
) != 0;
8252 child
->xshrink
= (xoptions
& GTK_SHRINK
) != 0;
8253 child
->yshrink
= (yoptions
& GTK_SHRINK
) != 0;
8254 child
->xfill
= (xoptions
& GTK_FILL
) != 0;
8255 child
->yfill
= (yoptions
& GTK_FILL
) != 0;
8257 sheet
->children
= g_list_append(sheet
->children
, child
);
8259 gtk_sheet_get_cell_area(sheet
, row
, col
, &area
);
8261 child
->x
= area
.x
+ child
->xpadding
;
8262 child
->y
= area
.y
+ child
->ypadding
;
8264 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8266 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8267 (!GTK_WIDGET_REALIZED(widget
) || GTK_WIDGET_NO_WINDOW(widget
)))
8268 gtk_sheet_realize_child(sheet
, child
);
8270 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8271 !GTK_WIDGET_MAPPED(widget
))
8272 gtk_widget_map(widget
);
8275 gtk_sheet_position_child(sheet
, child
);
8277 /* This will avoid drawing on the titles */
8279 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)))
8281 if(GTK_SHEET_ROW_TITLES_VISIBLE(sheet
))
8282 gdk_window_show(sheet
->row_title_window
);
8283 if(GTK_SHEET_COL_TITLES_VISIBLE(sheet
))
8284 gdk_window_show(sheet
->column_title_window
);
8290 gtk_sheet_button_attach (GtkSheet
*sheet
,
8294 GtkSheetButton
*button
;
8295 GtkSheetChild
*child
;
8296 GtkRequisition button_requisition
;
8298 if(row
>= 0 && col
>= 0) return;
8299 if(row
< 0 && col
< 0) return;
8301 child
= g_new (GtkSheetChild
, 1);
8302 child
->widget
= widget
;
8305 child
->attached_to_cell
= TRUE
;
8306 child
->floating
= FALSE
;
8309 child
->xpadding
= child
->ypadding
= 0;
8310 child
->xshrink
= child
->yshrink
= FALSE
;
8311 child
->xfill
= child
->yfill
= FALSE
;
8314 button
= &sheet
->column
[col
].button
;
8315 button
->child
= child
;
8319 button
= &sheet
->row
[row
].button
;
8320 button
->child
= child
;
8323 sheet
->children
= g_list_append(sheet
->children
, child
);
8325 gtk_sheet_button_size_request(sheet
, button
, &button_requisition
);
8328 if(button_requisition
.height
> sheet
->column_title_area
.height
)
8329 sheet
->column_title_area
.height
= button_requisition
.height
;
8330 if(button_requisition
.width
> sheet
->column
[col
].width
)
8331 sheet
->column
[col
].width
= button_requisition
.width
;
8335 if(button_requisition
.width
> sheet
->row_title_area
.width
)
8336 sheet
->row_title_area
.width
= button_requisition
.width
;
8337 if(button_requisition
.height
> sheet
->row
[row
].height
)
8338 sheet
->row
[row
].height
= button_requisition
.height
;
8341 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet
)))
8343 if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet
)) &&
8344 (!GTK_WIDGET_REALIZED(widget
) || GTK_WIDGET_NO_WINDOW(widget
)))
8345 gtk_sheet_realize_child(sheet
, child
);
8347 if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet
)) &&
8348 !GTK_WIDGET_MAPPED(widget
))
8349 gtk_widget_map(widget
);
8352 if(row
== -1) size_allocate_column_title_buttons(sheet
);
8353 if(col
== -1) size_allocate_row_title_buttons(sheet
);
8358 label_size_request(GtkSheet
*sheet
, gchar
*label
, GtkRequisition
*req
)
8363 gint row_height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
)) - 2*CELLOFFSET
+ 2;
8369 while(words
&& *words
!= '\0'){
8370 if(*words
== '\n' || *(words
+1) == '\0'){
8371 req
->height
+= row_height
;
8374 req
->width
= MAX(req
->width
, STRING_WIDTH(GTK_WIDGET(sheet
), GTK_WIDGET(sheet
)->style
->font_desc
, word
));
8382 if(n
> 0) req
->height
-= 2;
8386 gtk_sheet_button_size_request (GtkSheet
*sheet
,
8387 GtkSheetButton
*button
,
8388 GtkRequisition
*button_requisition
)
8390 GtkRequisition requisition
;
8391 GtkRequisition label_requisition
;
8393 if(gtk_sheet_autoresize(sheet
) && button
->label
&& strlen(button
->label
) > 0){
8394 label_size_request(sheet
, button
->label
, &label_requisition
);
8395 label_requisition
.width
+= 2*CELLOFFSET
;
8396 label_requisition
.height
+= 2*CELLOFFSET
;
8398 label_requisition
.height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
8399 label_requisition
.width
= COLUMN_MIN_WIDTH
;
8404 gtk_widget_size_request(button
->child
->widget
, &requisition
);
8405 requisition
.width
+= 2*button
->child
->xpadding
;
8406 requisition
.height
+= 2*button
->child
->ypadding
;
8407 requisition
.width
+= 2*sheet
->button
->style
->xthickness
;
8408 requisition
.height
+= 2*sheet
->button
->style
->ythickness
;
8412 requisition
.height
= DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet
));
8413 requisition
.width
= COLUMN_MIN_WIDTH
;
8416 *button_requisition
= requisition
;
8417 button_requisition
->width
= MAX(requisition
.width
, label_requisition
.width
);
8418 button_requisition
->height
= MAX(requisition
.height
, label_requisition
.height
);
8423 gtk_sheet_row_size_request (GtkSheet
*sheet
,
8427 GtkRequisition button_requisition
;
8430 gtk_sheet_button_size_request(sheet
, &sheet
->row
[row
].button
, &button_requisition
);
8432 *requisition
= button_requisition
.height
;
8434 children
= sheet
->children
;
8436 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
8437 GtkRequisition child_requisition
;
8439 if(child
->attached_to_cell
&& child
->row
== row
&& child
->col
!= -1 && !child
->floating
&& !child
->yshrink
){
8440 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8442 if(child_requisition
.height
+ 2 * child
->ypadding
> *requisition
)
8443 *requisition
= child_requisition
.height
+ 2 * child
->ypadding
;
8445 children
= g_list_next(children
);
8448 sheet
->row
[row
].requisition
= *requisition
;
8452 gtk_sheet_column_size_request (GtkSheet
*sheet
,
8456 GtkRequisition button_requisition
;
8459 gtk_sheet_button_size_request(sheet
, &sheet
->column
[col
].button
, &button_requisition
);
8461 *requisition
= button_requisition
.width
;
8463 children
= sheet
->children
;
8465 GtkSheetChild
*child
= (GtkSheetChild
*)children
->data
;
8466 GtkRequisition child_requisition
;
8468 if(child
->attached_to_cell
&& child
->col
== col
&& child
->row
!= -1 && !child
->floating
&& !child
->xshrink
){
8469 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8471 if(child_requisition
.width
+ 2 * child
->xpadding
> *requisition
)
8472 *requisition
= child_requisition
.width
+ 2 * child
->xpadding
;
8474 children
= g_list_next(children
);
8477 sheet
->column
[col
].requisition
= *requisition
;
8481 gtk_sheet_move_child(GtkSheet
*sheet
, GtkWidget
*widget
, gint x
, gint y
)
8483 GtkSheetChild
*child
;
8486 g_return_if_fail(sheet
!= NULL
);
8487 g_return_if_fail(GTK_IS_SHEET(sheet
));
8489 children
= sheet
->children
;
8492 child
= children
->data
;
8494 if(child
->widget
== widget
){
8497 child
->row
= ROW_FROM_YPIXEL(sheet
, y
);
8498 child
->col
= COLUMN_FROM_XPIXEL(sheet
, x
);
8499 gtk_sheet_position_child(sheet
, child
);
8503 children
= g_list_next(children
);
8506 g_warning("Widget must be a GtkSheet child");
8511 gtk_sheet_position_child(GtkSheet
*sheet
, GtkSheetChild
*child
)
8513 GtkRequisition child_requisition
;
8514 GtkAllocation child_allocation
;
8520 gtk_widget_get_child_requisition(child
->widget
, &child_requisition
);
8522 if(sheet
->column_titles_visible
)
8523 yoffset
= sheet
->column_title_area
.height
;
8525 if(sheet
->row_titles_visible
)
8526 xoffset
= sheet
->row_title_area
.width
;
8528 if(child
->attached_to_cell
){
8530 child->x = COLUMN_LEFT_XPIXEL(sheet, child->col);
8531 child->y = ROW_TOP_YPIXEL(sheet, child->row);
8533 if(sheet->row_titles_visible)
8534 child->x-=sheet->row_title_area.width;
8535 if(sheet->column_titles_visible)
8536 child->y-=sheet->column_title_area.height;
8538 width = sheet->column[child->col].width;
8539 height = sheet->row[child->row].height;
8542 gtk_sheet_get_cell_area(sheet
, child
->row
, child
->col
, &area
);
8543 child
->x
= area
.x
+ child
->xpadding
;
8544 child
->y
= area
.y
+ child
->ypadding
;
8546 if(!child
->floating
){
8547 if(child_requisition
.width
+ 2*child
->xpadding
<= sheet
->column
[child
->col
].width
){
8549 child_requisition
.width
= child_allocation
.width
= sheet
->column
[child
->col
].width
- 2*child
->xpadding
;
8552 child
->x
= area
.x
+ sheet
->column
[child
->col
].width
/ 2 -
8553 child_requisition
.width
/ 2;
8555 child_allocation
.width
= child_requisition
.width
;
8558 if(!child
->xshrink
){
8559 gtk_sheet_set_column_width(sheet
, child
->col
, child_requisition
.width
+ 2 * child
->xpadding
);
8561 child_allocation
.width
= sheet
->column
[child
->col
].width
- 2*child
->xpadding
;
8564 if(child_requisition
.height
+ 2*child
->ypadding
<= sheet
->row
[child
->row
].height
){
8566 child_requisition
.height
= child_allocation
.height
= sheet
->row
[child
->row
].height
- 2*child
->ypadding
;
8569 child
->y
= area
.y
+ sheet
->row
[child
->row
].height
/ 2 -
8570 child_requisition
.height
/ 2;
8572 child_allocation
.height
= child_requisition
.height
;
8575 if(!child
->yshrink
){
8576 gtk_sheet_set_row_height(sheet
, child
->row
, child_requisition
.height
+ 2 * child
->ypadding
);
8578 child_allocation
.height
= sheet
->row
[child
->row
].height
- 2*child
->ypadding
;
8581 child_allocation
.width
= child_requisition
.width
;
8582 child_allocation
.height
= child_requisition
.height
;
8585 x
= child_allocation
.x
= child
->x
+ xoffset
;
8586 y
= child_allocation
.y
= child
->y
+ yoffset
;
8590 x
= child_allocation
.x
= child
->x
+ sheet
->hoffset
+ xoffset
;
8591 x
= child_allocation
.x
= child
->x
+ xoffset
;
8592 y
= child_allocation
.y
= child
->y
+ sheet
->voffset
+ yoffset
;
8593 y
= child_allocation
.y
= child
->y
+ yoffset
;
8594 child_allocation
.width
= child_requisition
.width
;
8595 child_allocation
.height
= child_requisition
.height
;
8598 gtk_widget_size_allocate(child
->widget
, &child_allocation
);
8599 gtk_widget_queue_draw(child
->widget
);
8603 gtk_sheet_forall (GtkContainer
*container
,
8604 gboolean include_internals
,
8605 GtkCallback callback
,
8606 gpointer callback_data
)
8609 GtkSheetChild
*child
;
8612 g_return_if_fail (GTK_IS_SHEET (container
));
8613 g_return_if_fail (callback
!= NULL
);
8615 sheet
= GTK_SHEET (container
);
8617 children
= sheet
->children
;
8620 child
= children
->data
;
8621 children
= g_list_next(children
);
8623 (* callback
) (child
->widget
, callback_data
);
8626 (* callback
) (sheet
->button
, callback_data
);
8627 if(sheet
->sheet_entry
)
8628 (* callback
) (sheet
->sheet_entry
, callback_data
);
8633 gtk_sheet_position_children(GtkSheet
*sheet
)
8636 GtkSheetChild
*child
;
8638 children
= sheet
->children
;
8642 child
= (GtkSheetChild
*)children
->data
;
8644 if(child
->col
!=-1 && child
->row
!= -1)
8645 gtk_sheet_position_child(sheet
, child
);
8647 if(child
->row
== -1){
8648 if(child
->col
< MIN_VISIBLE_COLUMN(sheet
) ||
8649 child
->col
> MAX_VISIBLE_COLUMN(sheet
))
8650 gtk_sheet_child_hide(child
);
8652 gtk_sheet_child_show(child
);
8654 if(child
->col
== -1){
8655 if(child
->row
< MIN_VISIBLE_ROW(sheet
) ||
8656 child
->row
> MAX_VISIBLE_ROW(sheet
))
8657 gtk_sheet_child_hide(child
);
8659 gtk_sheet_child_show(child
);
8662 children
= g_list_next(children
);
8668 gtk_sheet_remove (GtkContainer
*container
, GtkWidget
*widget
)
8672 GtkSheetChild
*child
= 0;
8674 g_return_if_fail(container
!= NULL
);
8675 g_return_if_fail(GTK_IS_SHEET(container
));
8677 sheet
= GTK_SHEET(container
);
8679 children
= sheet
->children
;
8683 child
= (GtkSheetChild
*)children
->data
;
8685 if(child
->widget
== widget
) break;
8687 children
= g_list_next(children
);
8692 if(child
->row
== -1)
8693 sheet
->row
[child
->col
].button
.child
= NULL
;
8695 if(child
->col
== -1)
8696 sheet
->column
[child
->row
].button
.child
= NULL
;
8698 gtk_widget_unparent (widget
);
8699 child
->widget
= NULL
;
8701 sheet
->children
= g_list_remove_link (sheet
->children
, children
);
8702 g_list_free_1 (children
);
8709 gtk_sheet_realize_child(GtkSheet
*sheet
, GtkSheetChild
*child
)
8713 widget
= GTK_WIDGET(sheet
);
8715 if(GTK_WIDGET_REALIZED(widget
)){
8716 if(child
->row
== -1)
8717 gtk_widget_set_parent_window(child
->widget
, sheet
->column_title_window
);
8718 else if(child
->col
== -1)
8719 gtk_widget_set_parent_window(child
->widget
, sheet
->row_title_window
);
8721 gtk_widget_set_parent_window(child
->widget
, sheet
->sheet_window
);
8724 gtk_widget_set_parent(child
->widget
, widget
);
8730 gtk_sheet_get_child_at(GtkSheet
*sheet
, gint row
, gint col
)
8733 GtkSheetChild
*child
= 0;
8735 g_return_val_if_fail(sheet
!= NULL
, NULL
);
8736 g_return_val_if_fail(GTK_IS_SHEET(sheet
), NULL
);
8738 children
= sheet
->children
;
8742 child
= (GtkSheetChild
*)children
->data
;
8744 if(child
->attached_to_cell
)
8745 if(child
->row
== row
&& child
->col
== col
) break;
8747 children
= g_list_next(children
);
8750 if(children
) return child
;
8756 gtk_sheet_child_hide(GtkSheetChild
*child
)
8758 g_return_if_fail(child
!= NULL
);
8759 gtk_widget_hide(child
->widget
);
8763 gtk_sheet_child_show(GtkSheetChild
*child
)
8765 g_return_if_fail(child
!= NULL
);
8767 gtk_widget_show(child
->widget
);