No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-table-model.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-table-model.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with the program; if not, see <http://www.gnu.org/licenses/>
15 *
16 *
17 * Authors:
18 * Chris Lahey <clahey@ximian.com>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include "e-util/e-util.h"
29
30 #include "e-table-model.h"
31
32 #define ETM_FROZEN(e) \
33 (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (e), "frozen")) != 0)
34
35 #define d(x)
36
37 d (static gint depth = 0;)
38
39 G_DEFINE_TYPE (ETableModel, e_table_model, G_TYPE_OBJECT)
40
41 enum {
42 MODEL_NO_CHANGE,
43 MODEL_CHANGED,
44 MODEL_PRE_CHANGE,
45 MODEL_ROW_CHANGED,
46 MODEL_CELL_CHANGED,
47 MODEL_ROWS_INSERTED,
48 MODEL_ROWS_DELETED,
49 ROW_SELECTION,
50 LAST_SIGNAL
51 };
52
53 static guint signals[LAST_SIGNAL] = { 0, };
54
55 /**
56 * e_table_model_column_count:
57 * @e_table_model: The e-table-model to operate on
58 *
59 * Returns: the number of columns in the table model.
60 */
61 gint
62 e_table_model_column_count (ETableModel *e_table_model)
63 {
64 ETableModelClass *class;
65
66 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0);
67
68 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
69 g_return_val_if_fail (class->column_count != NULL, 0);
70
71 return class->column_count (e_table_model);
72 }
73
74 /**
75 * e_table_model_row_count:
76 * @e_table_model: the e-table-model to operate on
77 *
78 * Returns: the number of rows in the Table model.
79 */
80 gint
81 e_table_model_row_count (ETableModel *e_table_model)
82 {
83 ETableModelClass *class;
84
85 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0);
86
87 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
88 g_return_val_if_fail (class->row_count != NULL, 0);
89
90 return class->row_count (e_table_model);
91 }
92
93 /**
94 * e_table_model_append_row:
95 * @e_table_model: the table model to append the a row to.
96 * @source:
97 * @row:
98 *
99 */
100 void
101 e_table_model_append_row (ETableModel *e_table_model,
102 ETableModel *source,
103 gint row)
104 {
105 ETableModelClass *class;
106
107 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
108
109 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
110
111 if (class->append_row != NULL)
112 class->append_row (e_table_model, source, row);
113 }
114
115 /**
116 * e_table_value_at:
117 * @e_table_model: the e-table-model to operate on
118 * @col: column in the model to pull data from.
119 * @row: row in the model to pull data from.
120 *
121 * Return value: This function returns the value that is stored
122 * by the @e_table_model in column @col and row @row. The data
123 * returned can be a pointer or any data value that can be stored
124 * inside a pointer.
125 *
126 * The data returned is typically used by an ECell renderer.
127 *
128 * The data returned must be valid until the model sends a signal that
129 * affect that piece of data. model_changed affects all data.
130 * row_changed affects the data in that row. cell_changed affects the
131 * data in that cell. rows_deleted affects all data in those rows.
132 * rows_inserted and no_change don't affect any data in this way.
133 **/
134 gpointer
135 e_table_model_value_at (ETableModel *e_table_model,
136 gint col,
137 gint row)
138 {
139 ETableModelClass *class;
140
141 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
142
143 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
144 g_return_val_if_fail (class->value_at != NULL, NULL);
145
146 return class->value_at (e_table_model, col, row);
147 }
148
149 /**
150 * e_table_model_set_value_at:
151 * @e_table_model: the table model to operate on.
152 * @col: the column where the data will be stored in the model.
153 * @row: the row where the data will be stored in the model.
154 * @value: the data to be stored.
155 *
156 * This function instructs the model to store the value in @data in the
157 * the @e_table_model at column @col and row @row. The @data typically
158 * comes from one of the ECell rendering objects.
159 *
160 * There should be an agreement between the Table Model and the user
161 * of this function about the data being stored. Typically it will
162 * be a pointer to a set of data, or a datum that fits inside a gpointer .
163 */
164 void
165 e_table_model_set_value_at (ETableModel *e_table_model,
166 gint col,
167 gint row,
168 gconstpointer value)
169 {
170 ETableModelClass *class;
171
172 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
173
174 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
175 g_return_if_fail (class->set_value_at != NULL);
176
177 class->set_value_at (e_table_model, col, row, value);
178 }
179
180 /**
181 * e_table_model_is_cell_editable:
182 * @e_table_model: the table model to query.
183 * @col: column to query.
184 * @row: row to query.
185 *
186 * Returns: %TRUE if the cell in @e_table_model at @col,@row can be
187 * edited, %FALSE otherwise
188 */
189 gboolean
190 e_table_model_is_cell_editable (ETableModel *e_table_model,
191 gint col,
192 gint row)
193 {
194 ETableModelClass *class;
195
196 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE);
197
198 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
199 g_return_val_if_fail (class->is_cell_editable != NULL, FALSE);
200
201 return class->is_cell_editable (e_table_model, col, row);
202 }
203
204 gpointer
205 e_table_model_duplicate_value (ETableModel *e_table_model,
206 gint col,
207 gconstpointer value)
208 {
209 ETableModelClass *class;
210
211 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
212
213 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
214
215 if (class->duplicate_value == NULL)
216 return NULL;
217
218 return class->duplicate_value (e_table_model, col, value);
219 }
220
221 void
222 e_table_model_free_value (ETableModel *e_table_model,
223 gint col,
224 gpointer value)
225 {
226 ETableModelClass *class;
227
228 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
229
230 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
231
232 if (class->free_value != NULL)
233 class->free_value (e_table_model, col, value);
234 }
235
236 gboolean
237 e_table_model_has_save_id (ETableModel *e_table_model)
238 {
239 ETableModelClass *class;
240
241 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE);
242
243 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
244
245 if (class->has_save_id == NULL)
246 return FALSE;
247
248 return class->has_save_id (e_table_model);
249 }
250
251 gchar *
252 e_table_model_get_save_id (ETableModel *e_table_model,
253 gint row)
254 {
255 ETableModelClass *class;
256
257 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
258
259 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
260
261 if (class->get_save_id == NULL)
262 return NULL;
263
264 return class->get_save_id (e_table_model, row);
265 }
266
267 gboolean
268 e_table_model_has_change_pending (ETableModel *e_table_model)
269 {
270 ETableModelClass *class;
271
272 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE);
273
274 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
275
276 if (class->has_change_pending == NULL)
277 return FALSE;
278
279 return class->has_change_pending (e_table_model);
280 }
281
282 gpointer
283 e_table_model_initialize_value (ETableModel *e_table_model,
284 gint col)
285 {
286 ETableModelClass *class;
287
288 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
289
290 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
291
292 if (class->initialize_value == NULL)
293 return NULL;
294
295 return class->initialize_value (e_table_model, col);
296 }
297
298 gboolean
299 e_table_model_value_is_empty (ETableModel *e_table_model,
300 gint col,
301 gconstpointer value)
302 {
303 ETableModelClass *class;
304
305 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE);
306
307 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
308
309 if (class->value_is_empty == NULL)
310 return FALSE;
311
312 return class->value_is_empty (e_table_model, col, value);
313 }
314
315 gchar *
316 e_table_model_value_to_string (ETableModel *e_table_model,
317 gint col,
318 gconstpointer value)
319 {
320 ETableModelClass *class;
321
322 g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
323
324 class = E_TABLE_MODEL_GET_CLASS (e_table_model);
325
326 if (class->value_to_string == NULL)
327 return g_strdup ("");
328
329 return class->value_to_string (e_table_model, col, value);
330 }
331
332 static void
333 e_table_model_class_init (ETableModelClass *class)
334 {
335 GObjectClass *object_class = G_OBJECT_CLASS (class);
336
337 signals[MODEL_NO_CHANGE] = g_signal_new (
338 "model_no_change",
339 G_TYPE_FROM_CLASS (object_class),
340 G_SIGNAL_RUN_LAST,
341 G_STRUCT_OFFSET (ETableModelClass, model_no_change),
342 (GSignalAccumulator) NULL, NULL,
343 g_cclosure_marshal_VOID__VOID,
344 G_TYPE_NONE, 0);
345
346 signals[MODEL_CHANGED] = g_signal_new (
347 "model_changed",
348 G_TYPE_FROM_CLASS (object_class),
349 G_SIGNAL_RUN_LAST,
350 G_STRUCT_OFFSET (ETableModelClass, model_changed),
351 (GSignalAccumulator) NULL, NULL,
352 g_cclosure_marshal_VOID__VOID,
353 G_TYPE_NONE, 0);
354
355 signals[MODEL_PRE_CHANGE] = g_signal_new (
356 "model_pre_change",
357 G_TYPE_FROM_CLASS (object_class),
358 G_SIGNAL_RUN_LAST,
359 G_STRUCT_OFFSET (ETableModelClass, model_pre_change),
360 (GSignalAccumulator) NULL, NULL,
361 g_cclosure_marshal_VOID__VOID,
362 G_TYPE_NONE, 0);
363
364 signals[MODEL_ROW_CHANGED] = g_signal_new (
365 "model_row_changed",
366 G_TYPE_FROM_CLASS (object_class),
367 G_SIGNAL_RUN_LAST,
368 G_STRUCT_OFFSET (ETableModelClass, model_row_changed),
369 (GSignalAccumulator) NULL, NULL,
370 g_cclosure_marshal_VOID__INT,
371 G_TYPE_NONE, 1,
372 G_TYPE_INT);
373
374 signals[MODEL_CELL_CHANGED] = g_signal_new (
375 "model_cell_changed",
376 G_TYPE_FROM_CLASS (object_class),
377 G_SIGNAL_RUN_LAST,
378 G_STRUCT_OFFSET (ETableModelClass, model_cell_changed),
379 (GSignalAccumulator) NULL, NULL,
380 e_marshal_VOID__INT_INT,
381 G_TYPE_NONE, 2,
382 G_TYPE_INT,
383 G_TYPE_INT);
384
385 signals[MODEL_ROWS_INSERTED] = g_signal_new (
386 "model_rows_inserted",
387 G_TYPE_FROM_CLASS (object_class),
388 G_SIGNAL_RUN_LAST,
389 G_STRUCT_OFFSET (ETableModelClass, model_rows_inserted),
390 (GSignalAccumulator) NULL, NULL,
391 e_marshal_VOID__INT_INT,
392 G_TYPE_NONE, 2,
393 G_TYPE_INT,
394 G_TYPE_INT);
395
396 signals[MODEL_ROWS_DELETED] = g_signal_new (
397 "model_rows_deleted",
398 G_TYPE_FROM_CLASS (object_class),
399 G_SIGNAL_RUN_LAST,
400 G_STRUCT_OFFSET (ETableModelClass, model_rows_deleted),
401 (GSignalAccumulator) NULL, NULL,
402 e_marshal_VOID__INT_INT,
403 G_TYPE_NONE, 2,
404 G_TYPE_INT,
405 G_TYPE_INT);
406
407 class->column_count = NULL;
408 class->row_count = NULL;
409 class->append_row = NULL;
410
411 class->value_at = NULL;
412 class->set_value_at = NULL;
413 class->is_cell_editable = NULL;
414
415 class->has_save_id = NULL;
416 class->get_save_id = NULL;
417
418 class->has_change_pending = NULL;
419
420 class->duplicate_value = NULL;
421 class->free_value = NULL;
422 class->initialize_value = NULL;
423 class->value_is_empty = NULL;
424 class->value_to_string = NULL;
425
426 class->model_no_change = NULL;
427 class->model_changed = NULL;
428 class->model_row_changed = NULL;
429 class->model_cell_changed = NULL;
430 class->model_rows_inserted = NULL;
431 class->model_rows_deleted = NULL;
432 }
433
434 static void
435 e_table_model_init (ETableModel *e_table_model)
436 {
437 /* nothing to do */
438 }
439
440 #if d(!)0
441 static void
442 print_tabs (void)
443 {
444 gint i;
445 for (i = 0; i < depth; i++)
446 g_print ("\t");
447 }
448 #endif
449
450 void
451 e_table_model_pre_change (ETableModel *e_table_model)
452 {
453 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
454
455 if (ETM_FROZEN (e_table_model))
456 return;
457
458 d (print_tabs ());
459 d (depth++);
460 g_signal_emit (e_table_model, signals[MODEL_PRE_CHANGE], 0);
461 d (depth--);
462 }
463
464 /**
465 * e_table_model_no_change:
466 * @e_table_model: the table model to notify of the lack of a change
467 *
468 * Use this function to notify any views of this table model that
469 * the contents of the table model have changed. This will emit
470 * the signal "model_no_change" on the @e_table_model object.
471 *
472 * It is preferable to use the e_table_model_row_changed() and
473 * the e_table_model_cell_changed() to notify of smaller changes
474 * than to invalidate the entire model, as the views might have
475 * ways of caching the information they render from the model.
476 */
477 void
478 e_table_model_no_change (ETableModel *e_table_model)
479 {
480 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
481
482 if (ETM_FROZEN (e_table_model))
483 return;
484
485 d (print_tabs ());
486 d (depth++);
487 g_signal_emit (e_table_model, signals[MODEL_NO_CHANGE], 0);
488 d (depth--);
489 }
490
491 /**
492 * e_table_model_changed:
493 * @e_table_model: the table model to notify of the change
494 *
495 * Use this function to notify any views of this table model that
496 * the contents of the table model have changed. This will emit
497 * the signal "model_changed" on the @e_table_model object.
498 *
499 * It is preferable to use the e_table_model_row_changed() and
500 * the e_table_model_cell_changed() to notify of smaller changes
501 * than to invalidate the entire model, as the views might have
502 * ways of caching the information they render from the model.
503 */
504 void
505 e_table_model_changed (ETableModel *e_table_model)
506 {
507 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
508
509 if (ETM_FROZEN (e_table_model))
510 return;
511
512 d (print_tabs ());
513 d (depth++);
514 g_signal_emit (e_table_model, signals[MODEL_CHANGED], 0);
515 d (depth--);
516 }
517
518 /**
519 * e_table_model_row_changed:
520 * @e_table_model: the table model to notify of the change
521 * @row: the row that was changed in the model.
522 *
523 * Use this function to notify any views of the table model that
524 * the contents of row @row have changed in model. This function
525 * will emit the "model_row_changed" signal on the @e_table_model
526 * object
527 */
528 void
529 e_table_model_row_changed (ETableModel *e_table_model,
530 gint row)
531 {
532 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
533
534 if (ETM_FROZEN (e_table_model))
535 return;
536
537 d (print_tabs ());
538 d (depth++);
539 g_signal_emit (e_table_model, signals[MODEL_ROW_CHANGED], 0, row);
540 d (depth--);
541 }
542
543 /**
544 * e_table_model_cell_changed:
545 * @e_table_model: the table model to notify of the change
546 * @col: the column.
547 * @row: the row
548 *
549 * Use this function to notify any views of the table model that
550 * contents of the cell at @col,@row has changed. This will emit
551 * the "model_cell_changed" signal on the @e_table_model
552 * object
553 */
554 void
555 e_table_model_cell_changed (ETableModel *e_table_model,
556 gint col,
557 gint row)
558 {
559 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
560
561 if (ETM_FROZEN (e_table_model))
562 return;
563
564 d (print_tabs ());
565 d (depth++);
566 g_signal_emit (
567 e_table_model, signals[MODEL_CELL_CHANGED], 0, col, row);
568 d (depth--);
569 }
570
571 /**
572 * e_table_model_rows_inserted:
573 * @e_table_model: the table model to notify of the change
574 * @row: the row that was inserted into the model.
575 * @count: The number of rows that were inserted.
576 *
577 * Use this function to notify any views of the table model that
578 * @count rows at row @row have been inserted into the model. This
579 * function will emit the "model_rows_inserted" signal on the
580 * @e_table_model object
581 */
582 void
583 e_table_model_rows_inserted (ETableModel *e_table_model,
584 gint row,
585 gint count)
586 {
587 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
588
589 if (ETM_FROZEN (e_table_model))
590 return;
591
592 d (print_tabs ());
593 d (depth++);
594 g_signal_emit (
595 e_table_model, signals[MODEL_ROWS_INSERTED], 0, row, count);
596 d (depth--);
597 }
598
599 /**
600 * e_table_model_row_inserted:
601 * @e_table_model: the table model to notify of the change
602 * @row: the row that was inserted into the model.
603 *
604 * Use this function to notify any views of the table model that the
605 * row @row has been inserted into the model. This function will emit
606 * the "model_rows_inserted" signal on the @e_table_model object
607 */
608 void
609 e_table_model_row_inserted (ETableModel *e_table_model,
610 gint row)
611 {
612 e_table_model_rows_inserted (e_table_model, row, 1);
613 }
614
615 /**
616 * e_table_model_row_deleted:
617 * @e_table_model: the table model to notify of the change
618 * @row: the row that was deleted
619 * @count: The number of rows deleted
620 *
621 * Use this function to notify any views of the table model that
622 * @count rows at row @row have been deleted from the model. This
623 * function will emit the "model_rows_deleted" signal on the
624 * @e_table_model object
625 */
626 void
627 e_table_model_rows_deleted (ETableModel *e_table_model,
628 gint row,
629 gint count)
630 {
631 g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
632
633 if (ETM_FROZEN (e_table_model))
634 return;
635
636 d (print_tabs ());
637 d (depth++);
638 g_signal_emit (
639 e_table_model, signals[MODEL_ROWS_DELETED], 0, row, count);
640 d (depth--);
641 }
642
643 /**
644 * e_table_model_row_deleted:
645 * @e_table_model: the table model to notify of the change
646 * @row: the row that was deleted
647 *
648 * Use this function to notify any views of the table model that the
649 * row @row has been deleted from the model. This function will emit
650 * the "model_rows_deleted" signal on the @e_table_model object
651 */
652 void
653 e_table_model_row_deleted (ETableModel *e_table_model,
654 gint row)
655 {
656 e_table_model_rows_deleted (e_table_model, row, 1);
657 }
658
659 void
660 e_table_model_freeze (ETableModel *e_table_model)
661 {
662 e_table_model_pre_change (e_table_model);
663
664 /* FIXME This expression is awesome! */
665 g_object_set_data (
666 G_OBJECT (e_table_model), "frozen",
667 GINT_TO_POINTER (GPOINTER_TO_INT (
668 g_object_get_data (G_OBJECT (e_table_model), "frozen")) + 1));
669 }
670
671 void
672 e_table_model_thaw (ETableModel *e_table_model)
673 {
674 /* FIXME This expression is awesome! */
675 g_object_set_data (
676 G_OBJECT (e_table_model), "frozen",
677 GINT_TO_POINTER (GPOINTER_TO_INT (
678 g_object_get_data (G_OBJECT (e_table_model), "frozen")) - 1));
679
680 e_table_model_changed (e_table_model);
681 }