No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-selection-model.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-selection-model.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
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 <gdk/gdkkeysyms.h>
28
29 #include <glib/gi18n.h>
30 #include "e-util/e-util.h"
31
32 #include "e-selection-model.h"
33
34 G_DEFINE_TYPE (
35 ESelectionModel,
36 e_selection_model,
37 G_TYPE_OBJECT)
38
39 enum {
40 CURSOR_CHANGED,
41 CURSOR_ACTIVATED,
42 SELECTION_CHANGED,
43 SELECTION_ROW_CHANGED,
44 LAST_SIGNAL
45 };
46
47 static guint signals[LAST_SIGNAL] = { 0, };
48
49 enum {
50 PROP_0,
51 PROP_SORTER,
52 PROP_SELECTION_MODE,
53 PROP_CURSOR_MODE
54 };
55
56 inline static void
57 add_sorter (ESelectionModel *esm,
58 ESorter *sorter)
59 {
60 esm->sorter = sorter;
61 if (sorter) {
62 g_object_ref (sorter);
63 }
64 }
65
66 inline static void
67 drop_sorter (ESelectionModel *esm)
68 {
69 if (esm->sorter) {
70 g_object_unref (esm->sorter);
71 }
72 esm->sorter = NULL;
73 }
74
75 static void
76 esm_dispose (GObject *object)
77 {
78 ESelectionModel *esm;
79
80 esm = E_SELECTION_MODEL (object);
81
82 drop_sorter (esm);
83
84 /* Chain up to parent's dispose() method. */
85 G_OBJECT_CLASS (e_selection_model_parent_class)->dispose (object);
86 }
87
88 static void
89 esm_get_property (GObject *object,
90 guint property_id,
91 GValue *value,
92 GParamSpec *pspec)
93 {
94 ESelectionModel *esm = E_SELECTION_MODEL (object);
95
96 switch (property_id) {
97 case PROP_SORTER:
98 g_value_set_object (value, esm->sorter);
99 break;
100
101 case PROP_SELECTION_MODE:
102 g_value_set_int (value, esm->mode);
103 break;
104
105 case PROP_CURSOR_MODE:
106 g_value_set_int (value, esm->cursor_mode);
107 break;
108 }
109 }
110
111 static void
112 esm_set_property (GObject *object,
113 guint property_id,
114 const GValue *value,
115 GParamSpec *pspec)
116 {
117 ESelectionModel *esm = E_SELECTION_MODEL (object);
118
119 switch (property_id) {
120 case PROP_SORTER:
121 drop_sorter (esm);
122 add_sorter (
123 esm, g_value_get_object (value) ?
124 E_SORTER (g_value_get_object (value)) : NULL);
125 break;
126
127 case PROP_SELECTION_MODE:
128 esm->mode = g_value_get_int (value);
129 if (esm->mode == GTK_SELECTION_SINGLE) {
130 gint cursor_row = e_selection_model_cursor_row (esm);
131 gint cursor_col = e_selection_model_cursor_col (esm);
132 e_selection_model_do_something (esm, cursor_row, cursor_col, 0);
133 }
134 break;
135
136 case PROP_CURSOR_MODE:
137 esm->cursor_mode = g_value_get_int (value);
138 break;
139 }
140 }
141
142 static void
143 e_selection_model_init (ESelectionModel *selection)
144 {
145 selection->mode = GTK_SELECTION_MULTIPLE;
146 selection->cursor_mode = E_CURSOR_SIMPLE;
147 selection->old_selection = -1;
148 }
149
150 static void
151 e_selection_model_class_init (ESelectionModelClass *class)
152 {
153 GObjectClass *object_class;
154
155 object_class = G_OBJECT_CLASS (class);
156 object_class->dispose = esm_dispose;
157 object_class->get_property = esm_get_property;
158 object_class->set_property = esm_set_property;
159
160 signals[CURSOR_CHANGED] = g_signal_new (
161 "cursor_changed",
162 G_OBJECT_CLASS_TYPE (object_class),
163 G_SIGNAL_RUN_LAST,
164 G_STRUCT_OFFSET (ESelectionModelClass, cursor_changed),
165 NULL, NULL,
166 e_marshal_NONE__INT_INT,
167 G_TYPE_NONE, 2,
168 G_TYPE_INT,
169 G_TYPE_INT);
170
171 signals[CURSOR_ACTIVATED] = g_signal_new (
172 "cursor_activated",
173 G_OBJECT_CLASS_TYPE (object_class),
174 G_SIGNAL_RUN_LAST,
175 G_STRUCT_OFFSET (ESelectionModelClass, cursor_activated),
176 NULL, NULL,
177 e_marshal_NONE__INT_INT,
178 G_TYPE_NONE, 2,
179 G_TYPE_INT,
180 G_TYPE_INT);
181
182 signals[SELECTION_CHANGED] = g_signal_new (
183 "selection_changed",
184 G_OBJECT_CLASS_TYPE (object_class),
185 G_SIGNAL_RUN_LAST,
186 G_STRUCT_OFFSET (ESelectionModelClass, selection_changed),
187 NULL, NULL,
188 g_cclosure_marshal_VOID__VOID,
189 G_TYPE_NONE, 0);
190
191 signals[SELECTION_ROW_CHANGED] = g_signal_new (
192 "selection_row_changed",
193 G_OBJECT_CLASS_TYPE (object_class),
194 G_SIGNAL_RUN_LAST,
195 G_STRUCT_OFFSET (ESelectionModelClass, selection_row_changed),
196 NULL, NULL,
197 g_cclosure_marshal_VOID__INT,
198 G_TYPE_NONE, 1,
199 G_TYPE_INT);
200
201 g_object_class_install_property (
202 object_class,
203 PROP_SORTER,
204 g_param_spec_object (
205 "sorter",
206 "Sorter",
207 NULL,
208 E_SORTER_TYPE,
209 G_PARAM_READWRITE));
210
211 g_object_class_install_property (
212 object_class,
213 PROP_SELECTION_MODE,
214 g_param_spec_int (
215 "selection_mode",
216 "Selection Mode",
217 NULL,
218 GTK_SELECTION_NONE,
219 GTK_SELECTION_MULTIPLE,
220 GTK_SELECTION_SINGLE,
221 G_PARAM_READWRITE));
222
223 g_object_class_install_property (
224 object_class,
225 PROP_CURSOR_MODE,
226 g_param_spec_int (
227 "cursor_mode",
228 "Cursor Mode",
229 NULL,
230 E_CURSOR_LINE,
231 E_CURSOR_SPREADSHEET,
232 E_CURSOR_LINE,
233 G_PARAM_READWRITE));
234 }
235
236 /**
237 * e_selection_model_is_row_selected
238 * @selection: #ESelectionModel to check
239 * @n: The row to check
240 *
241 * This routine calculates whether the given row is selected.
242 *
243 * Returns: %TRUE if the given row is selected
244 */
245 gboolean
246 e_selection_model_is_row_selected (ESelectionModel *selection,
247 gint n)
248 {
249 ESelectionModelClass *class;
250
251 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE);
252
253 class = E_SELECTION_MODEL_GET_CLASS (selection);
254 g_return_val_if_fail (class->is_row_selected != NULL, FALSE);
255
256 return class->is_row_selected (selection, n);
257 }
258
259 /**
260 * e_selection_model_foreach
261 * @selection: #ESelectionModel to traverse
262 * @callback: The callback function to call back.
263 * @closure: The closure
264 *
265 * This routine calls the given callback function once for each
266 * selected row, passing closure as the closure.
267 */
268 void
269 e_selection_model_foreach (ESelectionModel *selection,
270 EForeachFunc callback,
271 gpointer closure)
272 {
273 ESelectionModelClass *class;
274
275 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
276 g_return_if_fail (callback != NULL);
277
278 class = E_SELECTION_MODEL_GET_CLASS (selection);
279 g_return_if_fail (class->foreach != NULL);
280
281 class->foreach (selection, callback, closure);
282 }
283
284 /**
285 * e_selection_model_clear
286 * @selection: #ESelectionModel to clear
287 *
288 * This routine clears the selection to no rows selected.
289 */
290 void
291 e_selection_model_clear (ESelectionModel *selection)
292 {
293 ESelectionModelClass *class;
294
295 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
296
297 class = E_SELECTION_MODEL_GET_CLASS (selection);
298 g_return_if_fail (class->clear != NULL);
299
300 class->clear (selection);
301 }
302
303 /**
304 * e_selection_model_selected_count
305 * @selection: #ESelectionModel to count
306 *
307 * This routine calculates the number of rows selected.
308 *
309 * Returns: The number of rows selected in the given model.
310 */
311 gint
312 e_selection_model_selected_count (ESelectionModel *selection)
313 {
314 ESelectionModelClass *class;
315
316 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), 0);
317
318 class = E_SELECTION_MODEL_GET_CLASS (selection);
319 g_return_val_if_fail (class->selected_count != NULL, 0);
320
321 return class->selected_count (selection);
322 }
323
324 /**
325 * e_selection_model_select_all
326 * @selection: #ESelectionModel to select all
327 *
328 * This routine selects all the rows in the given
329 * #ESelectionModel.
330 */
331 void
332 e_selection_model_select_all (ESelectionModel *selection)
333 {
334 ESelectionModelClass *class;
335
336 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
337
338 class = E_SELECTION_MODEL_GET_CLASS (selection);
339 g_return_if_fail (class->select_all != NULL);
340
341 class->select_all (selection);
342 }
343
344 /**
345 * e_selection_model_invert_selection
346 * @selection: #ESelectionModel to invert
347 *
348 * This routine inverts all the rows in the given
349 * #ESelectionModel.
350 */
351 void
352 e_selection_model_invert_selection (ESelectionModel *selection)
353 {
354 ESelectionModelClass *class;
355
356 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
357
358 class = E_SELECTION_MODEL_GET_CLASS (selection);
359 g_return_if_fail (class->invert_selection != NULL);
360
361 class->invert_selection (selection);
362 }
363
364 gint
365 e_selection_model_row_count (ESelectionModel *selection)
366 {
367 ESelectionModelClass *class;
368
369 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), 0);
370
371 class = E_SELECTION_MODEL_GET_CLASS (selection);
372 g_return_val_if_fail (class->row_count != NULL, 0);
373
374 return class->row_count (selection);
375 }
376
377 void
378 e_selection_model_change_one_row (ESelectionModel *selection,
379 gint row,
380 gboolean grow)
381 {
382 ESelectionModelClass *class;
383
384 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
385
386 class = E_SELECTION_MODEL_GET_CLASS (selection);
387 g_return_if_fail (class->change_one_row != NULL);
388
389 return class->change_one_row (selection, row, grow);
390 }
391
392 void
393 e_selection_model_change_cursor (ESelectionModel *selection,
394 gint row,
395 gint col)
396 {
397 ESelectionModelClass *class;
398
399 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
400
401 class = E_SELECTION_MODEL_GET_CLASS (selection);
402 g_return_if_fail (class->change_cursor != NULL);
403
404 class->change_cursor (selection, row, col);
405 }
406
407 gint
408 e_selection_model_cursor_row (ESelectionModel *selection)
409 {
410 ESelectionModelClass *class;
411
412 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), -1);
413
414 class = E_SELECTION_MODEL_GET_CLASS (selection);
415 g_return_val_if_fail (class->cursor_row != NULL, -1);
416
417 return class->cursor_row (selection);
418 }
419
420 gint
421 e_selection_model_cursor_col (ESelectionModel *selection)
422 {
423 ESelectionModelClass *class;
424
425 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), -1);
426
427 class = E_SELECTION_MODEL_GET_CLASS (selection);
428 g_return_val_if_fail (class->cursor_col != NULL, -1);
429
430 return class->cursor_col (selection);
431 }
432
433 void
434 e_selection_model_select_single_row (ESelectionModel *selection,
435 gint row)
436 {
437 ESelectionModelClass *class;
438
439 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
440
441 class = E_SELECTION_MODEL_GET_CLASS (selection);
442 g_return_if_fail (class->select_single_row != NULL);
443
444 class->select_single_row (selection, row);
445 }
446
447 void
448 e_selection_model_toggle_single_row (ESelectionModel *selection,
449 gint row)
450 {
451 ESelectionModelClass *class;
452
453 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
454
455 class = E_SELECTION_MODEL_GET_CLASS (selection);
456 g_return_if_fail (class->toggle_single_row != NULL);
457
458 class->toggle_single_row (selection, row);
459 }
460
461 void
462 e_selection_model_move_selection_end (ESelectionModel *selection,
463 gint row)
464 {
465 ESelectionModelClass *class;
466
467 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
468
469 class = E_SELECTION_MODEL_GET_CLASS (selection);
470 g_return_if_fail (class->move_selection_end != NULL);
471
472 class->move_selection_end (selection, row);
473 }
474
475 void
476 e_selection_model_set_selection_end (ESelectionModel *selection,
477 gint row)
478 {
479 ESelectionModelClass *class;
480
481 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
482
483 class = E_SELECTION_MODEL_GET_CLASS (selection);
484 g_return_if_fail (class->set_selection_end != NULL);
485
486 class->set_selection_end (selection, row);
487 }
488
489 /**
490 * e_selection_model_do_something
491 * @selection: #ESelectionModel to do something to.
492 * @row: The row to do something in.
493 * @col: The col to do something in.
494 * @state: The state in which to do something.
495 *
496 * This routine does whatever is appropriate as if the user clicked
497 * the mouse in the given row and column.
498 */
499 void
500 e_selection_model_do_something (ESelectionModel *selection,
501 guint row,
502 guint col,
503 GdkModifierType state)
504 {
505 gint shift_p = state & GDK_SHIFT_MASK;
506 gint ctrl_p = state & GDK_CONTROL_MASK;
507 gint row_count;
508
509 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
510
511 selection->old_selection = -1;
512
513 if (row == -1 && col != -1)
514 row = 0;
515 if (col == -1 && row != -1)
516 col = 0;
517
518 row_count = e_selection_model_row_count (selection);
519 if (row_count >= 0 && row < row_count) {
520 switch (selection->mode) {
521 case GTK_SELECTION_SINGLE:
522 e_selection_model_select_single_row (selection, row);
523 break;
524 case GTK_SELECTION_BROWSE:
525 case GTK_SELECTION_MULTIPLE:
526 if (shift_p) {
527 e_selection_model_set_selection_end (selection, row);
528 } else {
529 if (ctrl_p) {
530 e_selection_model_toggle_single_row (selection, row);
531 } else {
532 e_selection_model_select_single_row (selection, row);
533 }
534 }
535 break;
536 default:
537 g_return_if_reached ();
538 break;
539 }
540 e_selection_model_change_cursor (selection, row, col);
541 g_signal_emit (
542 selection,
543 signals[CURSOR_CHANGED], 0,
544 row, col);
545 g_signal_emit (
546 selection,
547 signals[CURSOR_ACTIVATED], 0,
548 row, col);
549 }
550 }
551
552 /**
553 * e_selection_model_maybe_do_something
554 * @selection: #ESelectionModel to do something to.
555 * @row: The row to do something in.
556 * @col: The col to do something in.
557 * @state: The state in which to do something.
558 *
559 * If this row is selected, this routine just moves the cursor row and
560 * column. Otherwise, it does the same thing as
561 * e_selection_model_do_something(). This is for being used on
562 * right clicks and other events where if the user hit the selection,
563 * they don't want it to change.
564 */
565 gboolean
566 e_selection_model_maybe_do_something (ESelectionModel *selection,
567 guint row,
568 guint col,
569 GdkModifierType state)
570 {
571 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE);
572
573 selection->old_selection = -1;
574
575 if (e_selection_model_is_row_selected (selection, row)) {
576 e_selection_model_change_cursor (selection, row, col);
577 g_signal_emit (
578 selection,
579 signals[CURSOR_CHANGED], 0,
580 row, col);
581 return FALSE;
582 } else {
583 e_selection_model_do_something (selection, row, col, state);
584 return TRUE;
585 }
586 }
587
588 void
589 e_selection_model_right_click_down (ESelectionModel *selection,
590 guint row,
591 guint col,
592 GdkModifierType state)
593 {
594 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
595
596 if (selection->mode == GTK_SELECTION_SINGLE) {
597 selection->old_selection =
598 e_selection_model_cursor_row (selection);
599 e_selection_model_select_single_row (selection, row);
600 } else {
601 e_selection_model_maybe_do_something (
602 selection, row, col, state);
603 }
604 }
605
606 void
607 e_selection_model_right_click_up (ESelectionModel *selection)
608 {
609 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
610
611 if (selection->mode != GTK_SELECTION_SINGLE)
612 return;
613
614 if (selection->old_selection == -1)
615 return;
616
617 e_selection_model_select_single_row (
618 selection, selection->old_selection);
619 }
620
621 void
622 e_selection_model_select_as_key_press (ESelectionModel *selection,
623 guint row,
624 guint col,
625 GdkModifierType state)
626 {
627 gint cursor_activated = TRUE;
628
629 gint shift_p = state & GDK_SHIFT_MASK;
630 gint ctrl_p = state & GDK_CONTROL_MASK;
631
632 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
633
634 selection->old_selection = -1;
635
636 switch (selection->mode) {
637 case GTK_SELECTION_BROWSE:
638 case GTK_SELECTION_MULTIPLE:
639 if (shift_p) {
640 e_selection_model_set_selection_end (selection, row);
641 } else if (!ctrl_p) {
642 e_selection_model_select_single_row (selection, row);
643 } else
644 cursor_activated = FALSE;
645 break;
646 case GTK_SELECTION_SINGLE:
647 e_selection_model_select_single_row (selection, row);
648 break;
649 default:
650 g_return_if_reached ();
651 break;
652 }
653 if (row != -1) {
654 e_selection_model_change_cursor (selection, row, col);
655 g_signal_emit (
656 selection,
657 signals[CURSOR_CHANGED], 0,
658 row, col);
659 if (cursor_activated)
660 g_signal_emit (
661 selection,
662 signals[CURSOR_ACTIVATED], 0,
663 row, col);
664 }
665 }
666
667 static gint
668 move_selection (ESelectionModel *selection,
669 gboolean up,
670 GdkModifierType state)
671 {
672 gint row = e_selection_model_cursor_row (selection);
673 gint col = e_selection_model_cursor_col (selection);
674 gint row_count;
675
676 /* there is no selected row when row is -1 */
677 if (row != -1)
678 row = e_sorter_model_to_sorted (selection->sorter, row);
679
680 if (up)
681 row--;
682 else
683 row++;
684 if (row < 0)
685 row = 0;
686 row_count = e_selection_model_row_count (selection);
687 if (row >= row_count)
688 row = row_count - 1;
689 row = e_sorter_sorted_to_model (selection->sorter, row);
690
691 e_selection_model_select_as_key_press (selection, row, col, state);
692 return TRUE;
693 }
694
695 /**
696 * e_selection_model_key_press
697 * @selection: #ESelectionModel to affect.
698 * @key: The event.
699 *
700 * This routine does whatever is appropriate as if the user pressed
701 * the given key.
702 *
703 * Returns: %TRUE if the #ESelectionModel used the key.
704 */
705 gboolean
706 e_selection_model_key_press (ESelectionModel *selection,
707 GdkEventKey *key)
708 {
709 g_return_val_if_fail (E_IS_SELECTION_MODEL (selection), FALSE);
710 g_return_val_if_fail (key != NULL, FALSE);
711
712 selection->old_selection = -1;
713
714 switch (key->keyval) {
715 case GDK_KEY_Up:
716 case GDK_KEY_KP_Up:
717 return move_selection (selection, TRUE, key->state);
718 case GDK_KEY_Down:
719 case GDK_KEY_KP_Down:
720 return move_selection (selection, FALSE, key->state);
721 case GDK_KEY_space:
722 case GDK_KEY_KP_Space:
723 if (selection->mode != GTK_SELECTION_SINGLE) {
724 gint row = e_selection_model_cursor_row (selection);
725 gint col = e_selection_model_cursor_col (selection);
726 if (row == -1)
727 break;
728
729 e_selection_model_toggle_single_row (selection, row);
730 g_signal_emit (
731 selection,
732 signals[CURSOR_ACTIVATED], 0,
733 row, col);
734 return TRUE;
735 }
736 break;
737 case GDK_KEY_Return:
738 case GDK_KEY_KP_Enter:
739 if (selection->mode != GTK_SELECTION_SINGLE) {
740 gint row = e_selection_model_cursor_row (selection);
741 gint col = e_selection_model_cursor_col (selection);
742 e_selection_model_select_single_row (selection, row);
743 g_signal_emit (
744 selection,
745 signals[CURSOR_ACTIVATED], 0,
746 row, col);
747 return TRUE;
748 }
749 break;
750 case GDK_KEY_Home:
751 case GDK_KEY_KP_Home:
752 if (selection->cursor_mode == E_CURSOR_LINE) {
753 gint row = 0;
754 gint cursor_col = e_selection_model_cursor_col (selection);
755
756 row = e_sorter_sorted_to_model (selection->sorter, row);
757 e_selection_model_select_as_key_press (
758 selection, row, cursor_col, key->state);
759 return TRUE;
760 }
761 break;
762 case GDK_KEY_End:
763 case GDK_KEY_KP_End:
764 if (selection->cursor_mode == E_CURSOR_LINE) {
765 gint row = e_selection_model_row_count (selection) - 1;
766 gint cursor_col = e_selection_model_cursor_col (selection);
767
768 row = e_sorter_sorted_to_model (selection->sorter, row);
769 e_selection_model_select_as_key_press (
770 selection, row, cursor_col, key->state);
771 return TRUE;
772 }
773 break;
774 }
775 return FALSE;
776 }
777
778 void
779 e_selection_model_cursor_changed (ESelectionModel *selection,
780 gint row,
781 gint col)
782 {
783 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
784
785 g_signal_emit (selection, signals[CURSOR_CHANGED], 0, row, col);
786 }
787
788 void
789 e_selection_model_cursor_activated (ESelectionModel *selection,
790 gint row,
791 gint col)
792 {
793 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
794
795 g_signal_emit (selection, signals[CURSOR_ACTIVATED], 0, row, col);
796 }
797
798 void
799 e_selection_model_selection_changed (ESelectionModel *selection)
800 {
801 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
802
803 g_signal_emit (selection, signals[SELECTION_CHANGED], 0);
804 }
805
806 void
807 e_selection_model_selection_row_changed (ESelectionModel *selection,
808 gint row)
809 {
810 g_return_if_fail (E_IS_SELECTION_MODEL (selection));
811
812 g_signal_emit (selection, signals[SELECTION_ROW_CHANGED], 0, row);
813 }