evolution-3.6.4/widgets/table/e-table-group.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Chris Lahey <clahey@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include <gtk/gtk.h>
 28 #include <libgnomecanvas/libgnomecanvas.h>
 29 
 30 #include "e-util/e-util.h"
 31 
 32 #include "e-table-group.h"
 33 #include "e-table-group-container.h"
 34 #include "e-table-group-leaf.h"
 35 #include "e-table-item.h"
 36 
 37 /* workaround for avoiding API breakage*/
 38 #define etg_get_type e_table_group_get_type
 39 G_DEFINE_TYPE (ETableGroup, etg, GNOME_TYPE_CANVAS_GROUP)
 40 
 41 #define ETG_CLASS(e) (E_TABLE_GROUP_CLASS(G_OBJECT_GET_CLASS(e)))
 42 
 43 enum {
 44 	CURSOR_CHANGE,
 45 	CURSOR_ACTIVATED,
 46 	DOUBLE_CLICK,
 47 	RIGHT_CLICK,
 48 	CLICK,
 49 	KEY_PRESS,
 50 	START_DRAG,
 51 	LAST_SIGNAL
 52 };
 53 
 54 static guint etg_signals[LAST_SIGNAL] = { 0, };
 55 
 56 static gboolean etg_get_focus (ETableGroup      *etg);
 57 
 58 static void
 59 etg_dispose (GObject *object)
 60 {
 61 	ETableGroup *etg = E_TABLE_GROUP (object);
 62 
 63 	if (etg->header) {
 64 		g_object_unref (etg->header);
 65 		etg->header = NULL;
 66 	}
 67 
 68 	if (etg->full_header) {
 69 		g_object_unref (etg->full_header);
 70 		etg->full_header = NULL;
 71 	}
 72 
 73 	if (etg->model) {
 74 		g_object_unref (etg->model);
 75 		etg->model = NULL;
 76 	}
 77 
 78 	/* Chain up to parent's dispose() method. */
 79 	G_OBJECT_CLASS (etg_parent_class)->dispose (object);
 80 }
 81 
 82 /**
 83  * e_table_group_new
 84  * @parent: The %GnomeCanvasGroup to create a child of.
 85  * @full_header: The full header of the %ETable.
 86  * @header: The current header of the %ETable.
 87  * @model: The %ETableModel of the %ETable.
 88  * @sort_info: The %ETableSortInfo of the %ETable.
 89  * @n: The grouping information object to group by.
 90  *
 91  * %ETableGroup is a collection of rows of an %ETable.  It's a
 92  * %GnomeCanvasItem.  There are two different forms.  If n < the
 93  * number of groupings in the given %ETableSortInfo, then the
 94  * %ETableGroup will need to contain other %ETableGroups, thus it
 95  * creates an %ETableGroupContainer.  Otherwise, it will just contain
 96  * an %ETableItem, and thus it creates an %ETableGroupLeaf.
 97  *
 98  * Returns: The new %ETableGroup.
 99  */
100 ETableGroup *
101 e_table_group_new (GnomeCanvasGroup *parent,
102                    ETableHeader *full_header,
103                    ETableHeader *header,
104                    ETableModel *model,
105                    ETableSortInfo *sort_info,
106                    gint n)
107 {
108 	g_return_val_if_fail (model != NULL, NULL);
109 
110 	if (n < e_table_sort_info_grouping_get_count (sort_info)) {
111 		return e_table_group_container_new (
112 			parent, full_header, header, model, sort_info, n);
113 	} else {
114 		return e_table_group_leaf_new (
115 			parent, full_header, header, model, sort_info);
116 	}
117 }
118 
119 /**
120  * e_table_group_construct
121  * @parent: The %GnomeCanvasGroup to create a child of.
122  * @etg: The %ETableGroup to construct.
123  * @full_header: The full header of the %ETable.
124  * @header: The current header of the %ETable.
125  * @model: The %ETableModel of the %ETable.
126  *
127  * This routine does the base construction of the %ETableGroup.
128  */
129 void
130 e_table_group_construct (GnomeCanvasGroup *parent,
131                          ETableGroup *etg,
132                          ETableHeader *full_header,
133                          ETableHeader *header,
134                          ETableModel *model)
135 {
136 	etg->full_header = full_header;
137 	g_object_ref (etg->full_header);
138 	etg->header = header;
139 	g_object_ref (etg->header);
140 	etg->model = model;
141 	g_object_ref (etg->model);
142 	g_object_set (etg, "parent", parent, NULL);
143 }
144 
145 /**
146  * e_table_group_add
147  * @etg: The %ETableGroup to add a row to
148  * @row: The row to add.
149  *
150  * This routine adds the given row from the %ETableModel to this set
151  * of rows.
152  */
153 void
154 e_table_group_add (ETableGroup *etg,
155                    gint row)
156 {
157 	g_return_if_fail (etg != NULL);
158 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
159 
160 	g_return_if_fail (ETG_CLASS (etg)->add != NULL);
161 	ETG_CLASS (etg)->add (etg, row);
162 }
163 
164 /**
165  * e_table_group_add_array
166  * @etg: The %ETableGroup to add to
167  * @array: The array to add.
168  * @count: The number of times to add
169  *
170  * This routine adds all the rows in the array to this set of rows.
171  * It assumes that the array is already sorted properly.
172  */
173 void
174 e_table_group_add_array (ETableGroup *etg,
175                          const gint *array,
176                          gint count)
177 {
178 	g_return_if_fail (etg != NULL);
179 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
180 
181 	g_return_if_fail (ETG_CLASS (etg)->add_array != NULL);
182 	ETG_CLASS (etg)->add_array (etg, array, count);
183 }
184 
185 /**
186  * e_table_group_add_all
187  * @etg: The %ETableGroup to add to
188  *
189  * This routine adds all the rows from the %ETableModel to this set
190  * of rows.
191  */
192 void
193 e_table_group_add_all (ETableGroup *etg)
194 {
195 	g_return_if_fail (etg != NULL);
196 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
197 
198 	g_return_if_fail (ETG_CLASS (etg)->add_all != NULL);
199 	ETG_CLASS (etg)->add_all (etg);
200 }
201 
202 /**
203  * e_table_group_remove
204  * @etg: The %ETableGroup to remove a row from
205  * @row: The row to remove.
206  *
207  * This routine removes the given row from the %ETableModel from this
208  * set of rows.
209  *
210  * Returns: TRUE if the row was deleted and FALSE if the row was not
211  * found.
212  */
213 gboolean
214 e_table_group_remove (ETableGroup *etg,
215                       gint row)
216 {
217 	g_return_val_if_fail (etg != NULL, FALSE);
218 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
219 
220 	g_return_val_if_fail (ETG_CLASS (etg)->remove != NULL, FALSE);
221 	return ETG_CLASS (etg)->remove (etg, row);
222 }
223 
224 /**
225  * e_table_group_increment
226  * @etg: The %ETableGroup to increment
227  * @position: The position to increment from
228  * @amount: The amount to increment.
229  *
230  * This routine adds amount to all rows greater than or equal to
231  * position.  This is to handle when a row gets inserted into the
232  * model.
233  */
234 void
235 e_table_group_increment (ETableGroup *etg,
236                          gint position,
237                          gint amount)
238 {
239 	g_return_if_fail (etg != NULL);
240 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
241 
242 	g_return_if_fail (ETG_CLASS (etg)->increment != NULL);
243 	ETG_CLASS (etg)->increment (etg, position, amount);
244 }
245 
246 /**
247  * e_table_group_increment
248  * @etg: The %ETableGroup to decrement
249  * @position: The position to decrement from
250  * @amount: The amount to decrement
251  *
252  * This routine removes amount from all rows greater than or equal to
253  * position.  This is to handle when a row gets deleted from the
254  * model.
255  */
256 void
257 e_table_group_decrement (ETableGroup *etg,
258                          gint position,
259                          gint amount)
260 {
261 	g_return_if_fail (etg != NULL);
262 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
263 
264 	g_return_if_fail (ETG_CLASS (etg)->decrement != NULL);
265 	ETG_CLASS (etg)->decrement (etg, position, amount);
266 }
267 
268 /**
269  * e_table_group_increment
270  * @etg: The %ETableGroup to count
271  *
272  * This routine calculates the number of rows shown in this group.
273  *
274  * Returns: The number of rows.
275  */
276 gint
277 e_table_group_row_count (ETableGroup *etg)
278 {
279 	g_return_val_if_fail (etg != NULL, 0);
280 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), -1);
281 
282 	g_return_val_if_fail (ETG_CLASS (etg)->row_count != NULL, -1);
283 	return ETG_CLASS (etg)->row_count (etg);
284 }
285 
286 /**
287  * e_table_group_set_focus
288  * @etg: The %ETableGroup to set
289  * @direction: The direction the focus is coming from.
290  * @view_col: The column to set the focus in.
291  *
292  * Sets the focus to this widget.  Places the focus in the view column
293  * coming from direction direction.
294  */
295 void
296 e_table_group_set_focus (ETableGroup *etg,
297                          EFocus direction,
298                          gint view_col)
299 {
300 	g_return_if_fail (etg != NULL);
301 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
302 
303 	g_return_if_fail (ETG_CLASS (etg)->set_focus != NULL);
304 	ETG_CLASS (etg)->set_focus (etg, direction, view_col);
305 }
306 
307 /**
308  * e_table_group_get_focus
309  * @etg: The %ETableGroup to check
310  *
311  * Calculates if this group has the focus.
312  *
313  * Returns: TRUE if this group has the focus.
314  */
315 gboolean
316 e_table_group_get_focus (ETableGroup *etg)
317 {
318 	g_return_val_if_fail (etg != NULL, FALSE);
319 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
320 
321 	g_return_val_if_fail (ETG_CLASS (etg)->get_focus != NULL, FALSE);
322 	return ETG_CLASS (etg)->get_focus (etg);
323 }
324 
325 /**
326  * e_table_group_get_focus_column
327  * @etg: The %ETableGroup to check
328  *
329  * Calculates which column in this group has the focus.
330  *
331  * Returns: The column index (view column).
332  */
333 gint
334 e_table_group_get_focus_column (ETableGroup *etg)
335 {
336 	g_return_val_if_fail (etg != NULL, -1);
337 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), -1);
338 
339 	g_return_val_if_fail (ETG_CLASS (etg)->get_focus_column != NULL, -1);
340 	return ETG_CLASS (etg)->get_focus_column (etg);
341 }
342 
343 /**
344  * e_table_group_get_printable
345  * @etg: %ETableGroup which will be printed
346  *
347  * This routine creates and returns an %EPrintable that can be used to
348  * print the given %ETableGroup.
349  *
350  * Returns: The %EPrintable.
351  */
352 EPrintable *
353 e_table_group_get_printable (ETableGroup *etg)
354 {
355 	g_return_val_if_fail (etg != NULL, NULL);
356 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL);
357 
358 	g_return_val_if_fail (ETG_CLASS (etg)->get_printable != NULL, NULL);
359 	return ETG_CLASS (etg)->get_printable (etg);
360 }
361 
362 /**
363  * e_table_group_compute_location
364  * @eti: %ETableGroup to look in.
365  * @x: A pointer to the x location to find in the %ETableGroup.
366  * @y: A pointer to the y location to find in the %ETableGroup.
367  * @row: A pointer to the location to store the found row in.
368  * @col: A pointer to the location to store the found col in.
369  *
370  * This routine locates the pixel location (*x, *y) in the
371  * %ETableGroup.  If that location is in the %ETableGroup, *row and
372  * *col are set to the view row and column where it was found.  If
373  * that location is not in the %ETableGroup, the height of the
374  * %ETableGroup is removed from the value y points to.
375  */
376 void
377 e_table_group_compute_location (ETableGroup *etg,
378                                 gint *x,
379                                 gint *y,
380                                 gint *row,
381                                 gint *col)
382 {
383 	g_return_if_fail (etg != NULL);
384 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
385 
386 	g_return_if_fail (ETG_CLASS (etg)->compute_location != NULL);
387 	ETG_CLASS (etg)->compute_location (etg, x, y, row, col);
388 }
389 
390 void
391 e_table_group_get_mouse_over (ETableGroup *etg,
392                               gint *row,
393                               gint *col)
394 {
395 	g_return_if_fail (etg != NULL);
396 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
397 
398 	g_return_if_fail (ETG_CLASS (etg)->get_mouse_over != NULL);
399 	ETG_CLASS (etg)->get_mouse_over (etg, row, col);
400 }
401 
402 /**
403  * e_table_group_get_position
404  * @eti: %ETableGroup to look in.
405  * @x: A pointer to the location to store the found x location in.
406  * @y: A pointer to the location to store the found y location in.
407  * @row: A pointer to the row number to find.
408  * @col: A pointer to the col number to find.
409  *
410  * This routine finds the view cell (row, col) in the #ETableGroup.
411  * If that location is in the #ETableGroup *@x and *@y are set to the
412  * upper left hand corner of the cell found.  If that location is not
413  * in the #ETableGroup, the number of rows in the #ETableGroup is
414  * removed from the value row points to.
415  */
416 void
417 e_table_group_get_cell_geometry (ETableGroup *etg,
418                                  gint *row,
419                                  gint *col,
420                                  gint *x,
421                                  gint *y,
422                                  gint *width,
423                                  gint *height)
424 {
425 	g_return_if_fail (etg != NULL);
426 	g_return_if_fail (E_IS_TABLE_GROUP (etg));
427 
428 	g_return_if_fail (ETG_CLASS (etg)->get_cell_geometry != NULL);
429 	ETG_CLASS (etg)->get_cell_geometry (etg, row, col, x, y, width, height);
430 }
431 
432 /**
433  * e_table_group_cursor_change
434  * @eti: %ETableGroup to emit the signal on
435  * @row: The new cursor row (model row)
436  *
437  * This routine emits the "cursor_change" signal.
438  */
439 void
440 e_table_group_cursor_change (ETableGroup *e_table_group,
441                              gint row)
442 {
443 	g_return_if_fail (e_table_group != NULL);
444 	g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
445 
446 	g_signal_emit (
447 		e_table_group,
448 		etg_signals[CURSOR_CHANGE], 0,
449 		row);
450 }
451 
452 /**
453  * e_table_group_cursor_activated
454  * @eti: %ETableGroup to emit the signal on
455  * @row: The cursor row (model row)
456  *
457  * This routine emits the "cursor_activated" signal.
458  */
459 void
460 e_table_group_cursor_activated (ETableGroup *e_table_group,
461                                 gint row)
462 {
463 	g_return_if_fail (e_table_group != NULL);
464 	g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
465 
466 	g_signal_emit (
467 		e_table_group,
468 		etg_signals[CURSOR_ACTIVATED], 0,
469 		row);
470 }
471 
472 /**
473  * e_table_group_double_click
474  * @eti: %ETableGroup to emit the signal on
475  * @row: The row clicked on (model row)
476  * @col: The col clicked on (model col)
477  * @event: The event that caused this signal
478  *
479  * This routine emits the "double_click" signal.
480  */
481 void
482 e_table_group_double_click (ETableGroup *e_table_group,
483                             gint row,
484                             gint col,
485                             GdkEvent *event)
486 {
487 	g_return_if_fail (e_table_group != NULL);
488 	g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
489 
490 	g_signal_emit (
491 		e_table_group,
492 		etg_signals[DOUBLE_CLICK], 0,
493 		row, col, event);
494 }
495 
496 /**
497  * e_table_group_right_click
498  * @eti: %ETableGroup to emit the signal on
499  * @row: The row clicked on (model row)
500  * @col: The col clicked on (model col)
501  * @event: The event that caused this signal
502  *
503  * This routine emits the "right_click" signal.
504  */
505 gboolean
506 e_table_group_right_click (ETableGroup *e_table_group,
507                            gint row,
508                            gint col,
509                            GdkEvent *event)
510 {
511 	gboolean return_val = FALSE;
512 
513 	g_return_val_if_fail (e_table_group != NULL, FALSE);
514 	g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE);
515 
516 	g_signal_emit (
517 		e_table_group,
518 		etg_signals[RIGHT_CLICK], 0,
519 		row, col, event, &return_val);
520 
521 	return return_val;
522 }
523 
524 /**
525  * e_table_group_click
526  * @eti: %ETableGroup to emit the signal on
527  * @row: The row clicked on (model row)
528  * @col: The col clicked on (model col)
529  * @event: The event that caused this signal
530  *
531  * This routine emits the "click" signal.
532  */
533 gboolean
534 e_table_group_click (ETableGroup *e_table_group,
535                      gint row,
536                      gint col,
537                      GdkEvent *event)
538 {
539 	gboolean return_val = FALSE;
540 
541 	g_return_val_if_fail (e_table_group != NULL, FALSE);
542 	g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE);
543 
544 	g_signal_emit (
545 		e_table_group,
546 		etg_signals[CLICK], 0,
547 		row, col, event, &return_val);
548 
549 	return return_val;
550 }
551 
552 /**
553  * e_table_group_key_press
554  * @eti: %ETableGroup to emit the signal on
555  * @row: The cursor row (model row)
556  * @col: The cursor col (model col)
557  * @event: The event that caused this signal
558  *
559  * This routine emits the "key_press" signal.
560  */
561 gboolean
562 e_table_group_key_press (ETableGroup *e_table_group,
563                          gint row,
564                          gint col,
565                          GdkEvent *event)
566 {
567 	gboolean return_val = FALSE;
568 
569 	g_return_val_if_fail (e_table_group != NULL, FALSE);
570 	g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE);
571 
572 	g_signal_emit (
573 		e_table_group,
574 		etg_signals[KEY_PRESS], 0,
575 		row, col, event, &return_val);
576 
577 	return return_val;
578 }
579 
580 /**
581  * e_table_group_start_drag
582  * @eti: %ETableGroup to emit the signal on
583  * @row: The cursor row (model row)
584  * @col: The cursor col (model col)
585  * @event: The event that caused this signal
586  *
587  * This routine emits the "start_drag" signal.
588  */
589 gboolean
590 e_table_group_start_drag (ETableGroup *e_table_group,
591                           gint row,
592                           gint col,
593                           GdkEvent *event)
594 {
595 	gboolean return_val = FALSE;
596 
597 	g_return_val_if_fail (e_table_group != NULL, FALSE);
598 	g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), FALSE);
599 
600 	g_signal_emit (
601 		e_table_group,
602 		etg_signals[START_DRAG], 0,
603 		row, col, event, &return_val);
604 
605 	return return_val;
606 }
607 
608 /**
609  * e_table_group_get_header
610  * @eti: %ETableGroup to check
611  *
612  * This routine returns the %ETableGroup's header.
613  *
614  * Returns: The %ETableHeader.
615  */
616 ETableHeader *
617 e_table_group_get_header (ETableGroup *etg)
618 {
619 	g_return_val_if_fail (etg != NULL, NULL);
620 	g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL);
621 
622 	return etg->header;
623 }
624 
625 static gint
626 etg_event (GnomeCanvasItem *item,
627            GdkEvent *event)
628 {
629 	ETableGroup *etg = E_TABLE_GROUP (item);
630 	gboolean return_val = TRUE;
631 
632 	switch (event->type) {
633 
634 	case GDK_FOCUS_CHANGE:
635 		etg->has_focus = event->focus_change.in;
636 		return_val = FALSE;
637 		break;
638 
639 	default:
640 		return_val = FALSE;
641 	}
642 	if (return_val == FALSE) {
643 		if (GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->event)
644 			return GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->event (item, event);
645 	}
646 	return return_val;
647 
648 }
649 
650 static gboolean
651 etg_get_focus (ETableGroup *etg)
652 {
653 	return etg->has_focus;
654 }
655 
656 static void
657 etg_class_init (ETableGroupClass *class)
658 {
659 	GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (class);
660 	GObjectClass *object_class = G_OBJECT_CLASS (class);
661 
662 	object_class->dispose = etg_dispose;
663 
664 	item_class->event = etg_event;
665 
666 	class->cursor_change = NULL;
667 	class->cursor_activated = NULL;
668 	class->double_click = NULL;
669 	class->right_click = NULL;
670 	class->click = NULL;
671 	class->key_press = NULL;
672 	class->start_drag = NULL;
673 
674 	class->add = NULL;
675 	class->add_array = NULL;
676 	class->add_all = NULL;
677 	class->remove = NULL;
678 	class->row_count  = NULL;
679 	class->increment  = NULL;
680 	class->decrement  = NULL;
681 	class->set_focus  = NULL;
682 	class->get_focus = etg_get_focus;
683 	class->get_printable = NULL;
684 	class->compute_location = NULL;
685 	class->get_mouse_over = NULL;
686 	class->get_cell_geometry = NULL;
687 
688 	etg_signals[CURSOR_CHANGE] = g_signal_new (
689 		"cursor_change",
690 		G_OBJECT_CLASS_TYPE (object_class),
691 		G_SIGNAL_RUN_LAST,
692 		G_STRUCT_OFFSET (ETableGroupClass, cursor_change),
693 		NULL, NULL,
694 		g_cclosure_marshal_VOID__INT,
695 		G_TYPE_NONE, 1,
696 		G_TYPE_INT);
697 
698 	etg_signals[CURSOR_ACTIVATED] = g_signal_new (
699 		"cursor_activated",
700 		G_OBJECT_CLASS_TYPE (object_class),
701 		G_SIGNAL_RUN_LAST,
702 		G_STRUCT_OFFSET (ETableGroupClass, cursor_activated),
703 		NULL, NULL,
704 		g_cclosure_marshal_VOID__INT,
705 		G_TYPE_NONE, 1,
706 		G_TYPE_INT);
707 
708 	etg_signals[DOUBLE_CLICK] = g_signal_new (
709 		"double_click",
710 		G_OBJECT_CLASS_TYPE (object_class),
711 		G_SIGNAL_RUN_LAST,
712 		G_STRUCT_OFFSET (ETableGroupClass, double_click),
713 		NULL, NULL,
714 		e_marshal_NONE__INT_INT_BOXED,
715 		G_TYPE_NONE, 3,
716 		G_TYPE_INT,
717 		G_TYPE_INT,
718 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
719 
720 	etg_signals[RIGHT_CLICK] = g_signal_new (
721 		"right_click",
722 		G_OBJECT_CLASS_TYPE (object_class),
723 		G_SIGNAL_RUN_LAST,
724 		G_STRUCT_OFFSET (ETableGroupClass, right_click),
725 		g_signal_accumulator_true_handled, NULL,
726 		e_marshal_BOOLEAN__INT_INT_BOXED,
727 		G_TYPE_BOOLEAN, 3,
728 		G_TYPE_INT,
729 		G_TYPE_INT,
730 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
731 
732 	etg_signals[CLICK] = g_signal_new (
733 		"click",
734 		G_OBJECT_CLASS_TYPE (object_class),
735 		G_SIGNAL_RUN_LAST,
736 		G_STRUCT_OFFSET (ETableGroupClass, click),
737 		g_signal_accumulator_true_handled, NULL,
738 		e_marshal_BOOLEAN__INT_INT_BOXED,
739 		G_TYPE_BOOLEAN, 3,
740 		G_TYPE_INT,
741 		G_TYPE_INT,
742 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
743 
744 	etg_signals[KEY_PRESS] = g_signal_new (
745 		"key_press",
746 		G_OBJECT_CLASS_TYPE (object_class),
747 		G_SIGNAL_RUN_LAST,
748 		G_STRUCT_OFFSET (ETableGroupClass, key_press),
749 		g_signal_accumulator_true_handled, NULL,
750 		e_marshal_BOOLEAN__INT_INT_BOXED,
751 		G_TYPE_BOOLEAN, 3,
752 		G_TYPE_INT,
753 		G_TYPE_INT,
754 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
755 
756 	etg_signals[START_DRAG] = g_signal_new (
757 		"start_drag",
758 		G_OBJECT_CLASS_TYPE (object_class),
759 		G_SIGNAL_RUN_LAST,
760 		G_STRUCT_OFFSET (ETableGroupClass, start_drag),
761 		g_signal_accumulator_true_handled, NULL,
762 		e_marshal_BOOLEAN__INT_INT_BOXED,
763 		G_TYPE_BOOLEAN, 3,
764 		G_TYPE_INT,
765 		G_TYPE_INT,
766 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
767 }
768 
769 static void
770 etg_init (ETableGroup *etg)
771 {
772 	/* nothing to do */
773 }