3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Chris Lahey <clahey@ximian.com>
18 * Miguel de Icaza <miguel@ximian.com>
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
30 #include "e-table-subset.h"
32 #define E_TABLE_SUBSET_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_TABLE_SUBSET, ETableSubsetPrivate))
36 #define VALID_ROW(table_subset, row) \
37 (row >= -1 && row < table_subset->n_map)
38 #define MAP_ROW(table_subset, row) \
39 (row == -1 ? -1 : table_subset->map_table[row])
43 struct _ETableSubsetPrivate
{
44 ETableModel
*source_model
;
45 gulong table_model_pre_change_handler_id
;
46 gulong table_model_no_change_handler_id
;
47 gulong table_model_changed_handler_id
;
48 gulong table_model_row_changed_handler_id
;
49 gulong table_model_cell_changed_handler_id
;
50 gulong table_model_rows_inserted_handler_id
;
51 gulong table_model_rows_deleted_handler_id
;
56 /* Forward Declarations */
57 static void e_table_subset_table_model_init
58 (ETableModelInterface
*iface
);
60 G_DEFINE_TYPE_WITH_CODE (
64 G_IMPLEMENT_INTERFACE (
66 e_table_subset_table_model_init
))
69 table_subset_get_view_row (ETableSubset
*table_subset
,
72 const gint n
= table_subset
->n_map
;
73 const gint
* const map_table
= table_subset
->map_table
;
78 table_subset
->priv
->last_access
+ 10);
79 gint start
= MAX (0, table_subset
->priv
->last_access
- 10);
80 gint initial
= MAX (MIN (table_subset
->priv
->last_access
, end
), start
);
82 for (i
= initial
; i
< end
; i
++) {
83 if (map_table
[i
] == row
) {
84 table_subset
->priv
->last_access
= i
;
89 for (i
= initial
- 1; i
>= start
; i
--) {
90 if (map_table
[i
] == row
) {
91 table_subset
->priv
->last_access
= i
;
96 for (i
= 0; i
< n
; i
++) {
97 if (map_table
[i
] == row
) {
98 table_subset
->priv
->last_access
= i
;
106 table_subset_dispose (GObject
*object
)
108 ETableSubsetPrivate
*priv
;
110 priv
= E_TABLE_SUBSET_GET_PRIVATE (object
);
112 if (priv
->table_model_pre_change_handler_id
> 0) {
113 g_signal_handler_disconnect (
115 priv
->table_model_pre_change_handler_id
);
116 priv
->table_model_pre_change_handler_id
= 0;
119 if (priv
->table_model_no_change_handler_id
> 0) {
120 g_signal_handler_disconnect (
122 priv
->table_model_no_change_handler_id
);
123 priv
->table_model_no_change_handler_id
= 0;
126 if (priv
->table_model_changed_handler_id
> 0) {
127 g_signal_handler_disconnect (
129 priv
->table_model_changed_handler_id
);
130 priv
->table_model_changed_handler_id
= 0;
133 if (priv
->table_model_row_changed_handler_id
> 0) {
134 g_signal_handler_disconnect (
136 priv
->table_model_row_changed_handler_id
);
137 priv
->table_model_row_changed_handler_id
= 0;
140 if (priv
->table_model_cell_changed_handler_id
> 0) {
141 g_signal_handler_disconnect (
143 priv
->table_model_cell_changed_handler_id
);
144 priv
->table_model_cell_changed_handler_id
= 0;
147 if (priv
->table_model_rows_inserted_handler_id
> 0) {
148 g_signal_handler_disconnect (
150 priv
->table_model_rows_inserted_handler_id
);
151 priv
->table_model_rows_inserted_handler_id
= 0;
154 if (priv
->table_model_rows_deleted_handler_id
> 0) {
155 g_signal_handler_disconnect (
157 priv
->table_model_rows_deleted_handler_id
);
158 priv
->table_model_rows_deleted_handler_id
= 0;
161 g_clear_object (&priv
->source_model
);
163 /* Chain up to parent's dispose() method. */
164 G_OBJECT_CLASS (e_table_subset_parent_class
)->dispose (object
);
168 table_subset_finalize (GObject
*object
)
170 ETableSubset
*table_subset
;
172 table_subset
= E_TABLE_SUBSET (object
);
174 g_free (table_subset
->map_table
);
176 /* Chain up to parent's finalize() method. */
177 G_OBJECT_CLASS (e_table_subset_parent_class
)->finalize (object
);
181 table_subset_proxy_model_pre_change_real (ETableSubset
*table_subset
,
182 ETableModel
*source_model
)
184 e_table_model_pre_change (E_TABLE_MODEL (table_subset
));
188 table_subset_proxy_model_no_change_real (ETableSubset
*table_subset
,
189 ETableModel
*source_model
)
191 e_table_model_no_change (E_TABLE_MODEL (table_subset
));
195 table_subset_proxy_model_changed_real (ETableSubset
*table_subset
,
196 ETableModel
*source_model
)
198 e_table_model_changed (E_TABLE_MODEL (table_subset
));
202 table_subset_proxy_model_row_changed_real (ETableSubset
*table_subset
,
203 ETableModel
*source_model
,
206 gint view_row
= table_subset_get_view_row (table_subset
, row
);
209 e_table_model_row_changed (
210 E_TABLE_MODEL (table_subset
), view_row
);
212 e_table_model_no_change (E_TABLE_MODEL (table_subset
));
216 table_subset_proxy_model_cell_changed_real (ETableSubset
*table_subset
,
217 ETableModel
*source_model
,
221 gint view_row
= table_subset_get_view_row (table_subset
, row
);
224 e_table_model_cell_changed (
225 E_TABLE_MODEL (table_subset
), col
, view_row
);
227 e_table_model_no_change (E_TABLE_MODEL (table_subset
));
231 table_subset_proxy_model_rows_inserted_real (ETableSubset
*table_subset
,
232 ETableModel
*source_model
,
236 e_table_model_no_change (E_TABLE_MODEL (table_subset
));
240 table_subset_proxy_model_rows_deleted_real (ETableSubset
*table_subset
,
241 ETableModel
*source_model
,
245 e_table_model_no_change (E_TABLE_MODEL (table_subset
));
249 table_subset_column_count (ETableModel
*table_model
)
251 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
253 return e_table_model_column_count (table_subset
->priv
->source_model
);
257 table_subset_row_count (ETableModel
*table_model
)
259 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
261 return table_subset
->n_map
;
265 table_subset_value_at (ETableModel
*table_model
,
269 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
271 g_return_val_if_fail (VALID_ROW (table_subset
, row
), NULL
);
273 table_subset
->priv
->last_access
= row
;
275 return e_table_model_value_at (
276 table_subset
->priv
->source_model
,
277 col
, MAP_ROW (table_subset
, row
));
281 table_subset_set_value_at (ETableModel
*table_model
,
286 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
288 g_return_if_fail (VALID_ROW (table_subset
, row
));
290 table_subset
->priv
->last_access
= row
;
292 e_table_model_set_value_at (
293 table_subset
->priv
->source_model
,
294 col
, MAP_ROW (table_subset
, row
), val
);
298 table_subset_is_cell_editable (ETableModel
*table_model
,
302 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
304 g_return_val_if_fail (VALID_ROW (table_subset
, row
), FALSE
);
306 return e_table_model_is_cell_editable (
307 table_subset
->priv
->source_model
,
308 col
, MAP_ROW (table_subset
, row
));
312 table_subset_has_save_id (ETableModel
*table_model
)
318 table_subset_get_save_id (ETableModel
*table_model
,
321 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
323 g_return_val_if_fail (VALID_ROW (table_subset
, row
), NULL
);
325 if (e_table_model_has_save_id (table_subset
->priv
->source_model
))
326 return e_table_model_get_save_id (
327 table_subset
->priv
->source_model
,
328 MAP_ROW (table_subset
, row
));
330 return g_strdup_printf ("%d", MAP_ROW (table_subset
, row
));
334 table_subset_append_row (ETableModel
*table_model
,
338 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
340 e_table_model_append_row (
341 table_subset
->priv
->source_model
, source
, row
);
345 table_subset_duplicate_value (ETableModel
*table_model
,
349 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
351 return e_table_model_duplicate_value (
352 table_subset
->priv
->source_model
, col
, value
);
356 table_subset_free_value (ETableModel
*table_model
,
360 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
362 e_table_model_free_value (
363 table_subset
->priv
->source_model
, col
, value
);
367 table_subset_initialize_value (ETableModel
*table_model
,
370 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
372 return e_table_model_initialize_value (
373 table_subset
->priv
->source_model
, col
);
377 table_subset_value_is_empty (ETableModel
*table_model
,
381 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
383 return e_table_model_value_is_empty (
384 table_subset
->priv
->source_model
, col
, value
);
388 table_subset_value_to_string (ETableModel
*table_model
,
392 ETableSubset
*table_subset
= (ETableSubset
*) table_model
;
394 return e_table_model_value_to_string (
395 table_subset
->priv
->source_model
, col
, value
);
399 e_table_subset_class_init (ETableSubsetClass
*class)
401 GObjectClass
*object_class
;
403 g_type_class_add_private (class, sizeof (ETableSubsetPrivate
));
405 object_class
= G_OBJECT_CLASS (class);
406 object_class
->dispose
= table_subset_dispose
;
407 object_class
->finalize
= table_subset_finalize
;
409 class->proxy_model_pre_change
= table_subset_proxy_model_pre_change_real
;
410 class->proxy_model_no_change
= table_subset_proxy_model_no_change_real
;
411 class->proxy_model_changed
= table_subset_proxy_model_changed_real
;
412 class->proxy_model_row_changed
= table_subset_proxy_model_row_changed_real
;
413 class->proxy_model_cell_changed
= table_subset_proxy_model_cell_changed_real
;
414 class->proxy_model_rows_inserted
= table_subset_proxy_model_rows_inserted_real
;
415 class->proxy_model_rows_deleted
= table_subset_proxy_model_rows_deleted_real
;
419 e_table_subset_table_model_init (ETableModelInterface
*iface
)
421 iface
->column_count
= table_subset_column_count
;
422 iface
->row_count
= table_subset_row_count
;
423 iface
->append_row
= table_subset_append_row
;
425 iface
->value_at
= table_subset_value_at
;
426 iface
->set_value_at
= table_subset_set_value_at
;
427 iface
->is_cell_editable
= table_subset_is_cell_editable
;
429 iface
->has_save_id
= table_subset_has_save_id
;
430 iface
->get_save_id
= table_subset_get_save_id
;
432 iface
->duplicate_value
= table_subset_duplicate_value
;
433 iface
->free_value
= table_subset_free_value
;
434 iface
->initialize_value
= table_subset_initialize_value
;
435 iface
->value_is_empty
= table_subset_value_is_empty
;
436 iface
->value_to_string
= table_subset_value_to_string
;
440 e_table_subset_init (ETableSubset
*table_subset
)
442 table_subset
->priv
= E_TABLE_SUBSET_GET_PRIVATE (table_subset
);
446 table_subset_proxy_model_pre_change (ETableModel
*source_model
,
447 ETableSubset
*table_subset
)
449 ETableSubsetClass
*class;
451 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
453 if (class->proxy_model_pre_change
!= NULL
)
454 class->proxy_model_pre_change (table_subset
, source_model
);
458 table_subset_proxy_model_no_change (ETableModel
*source_model
,
459 ETableSubset
*table_subset
)
461 ETableSubsetClass
*class;
463 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
465 if (class->proxy_model_no_change
!= NULL
)
466 class->proxy_model_no_change (table_subset
, source_model
);
470 table_subset_proxy_model_changed (ETableModel
*source_model
,
471 ETableSubset
*table_subset
)
473 ETableSubsetClass
*class;
475 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
477 if (class->proxy_model_changed
!= NULL
)
478 class->proxy_model_changed (table_subset
, source_model
);
482 table_subset_proxy_model_row_changed (ETableModel
*source_model
,
484 ETableSubset
*table_subset
)
486 ETableSubsetClass
*class;
488 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
490 if (class->proxy_model_row_changed
!= NULL
)
491 class->proxy_model_row_changed (
492 table_subset
, source_model
, row
);
496 table_subset_proxy_model_cell_changed (ETableModel
*source_model
,
499 ETableSubset
*table_subset
)
501 ETableSubsetClass
*class;
503 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
505 if (class->proxy_model_cell_changed
!= NULL
)
506 class->proxy_model_cell_changed (
507 table_subset
, source_model
, col
, row
);
511 table_subset_proxy_model_rows_inserted (ETableModel
*source_model
,
514 ETableSubset
*table_subset
)
516 ETableSubsetClass
*class;
518 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
520 if (class->proxy_model_rows_inserted
!= NULL
)
521 class->proxy_model_rows_inserted (
522 table_subset
, source_model
, row
, col
);
526 table_subset_proxy_model_rows_deleted (ETableModel
*source_model
,
529 ETableSubset
*table_subset
)
531 ETableSubsetClass
*class;
533 class = E_TABLE_SUBSET_GET_CLASS (table_subset
);
535 if (class->proxy_model_rows_deleted
!= NULL
)
536 class->proxy_model_rows_deleted (
537 table_subset
, source_model
, row
, col
);
541 e_table_subset_construct (ETableSubset
*table_subset
,
542 ETableModel
*source_model
,
546 guint
*buffer
= NULL
;
550 buffer
= (guint
*) g_malloc (sizeof (guint
) * nvals
);
551 table_subset
->map_table
= (gint
*) buffer
;
552 table_subset
->n_map
= nvals
;
553 table_subset
->priv
->source_model
= g_object_ref (source_model
);
556 for (i
= 0; i
< nvals
; i
++)
557 table_subset
->map_table
[i
] = i
;
559 handler_id
= g_signal_connect (
560 source_model
, "model_pre_change",
561 G_CALLBACK (table_subset_proxy_model_pre_change
),
563 table_subset
->priv
->table_model_pre_change_handler_id
= handler_id
;
565 handler_id
= g_signal_connect (
566 source_model
, "model_no_change",
567 G_CALLBACK (table_subset_proxy_model_no_change
),
569 table_subset
->priv
->table_model_no_change_handler_id
= handler_id
;
571 handler_id
= g_signal_connect (
572 source_model
, "model_changed",
573 G_CALLBACK (table_subset_proxy_model_changed
),
575 table_subset
->priv
->table_model_changed_handler_id
= handler_id
;
577 handler_id
= g_signal_connect (
578 source_model
, "model_row_changed",
579 G_CALLBACK (table_subset_proxy_model_row_changed
),
581 table_subset
->priv
->table_model_row_changed_handler_id
= handler_id
;
583 handler_id
= g_signal_connect (
584 source_model
, "model_cell_changed",
585 G_CALLBACK (table_subset_proxy_model_cell_changed
),
587 table_subset
->priv
->table_model_cell_changed_handler_id
= handler_id
;
589 handler_id
= g_signal_connect (
590 source_model
, "model_rows_inserted",
591 G_CALLBACK (table_subset_proxy_model_rows_inserted
),
593 table_subset
->priv
->table_model_rows_inserted_handler_id
= handler_id
;
595 handler_id
= g_signal_connect (
596 source_model
, "model_rows_deleted",
597 G_CALLBACK (table_subset_proxy_model_rows_deleted
),
599 table_subset
->priv
->table_model_rows_deleted_handler_id
= handler_id
;
601 return E_TABLE_MODEL (table_subset
);
605 e_table_subset_new (ETableModel
*source_model
,
608 ETableSubset
*table_subset
;
610 g_return_val_if_fail (E_IS_TABLE_MODEL (source_model
), NULL
);
612 table_subset
= g_object_new (E_TYPE_TABLE_SUBSET
, NULL
);
614 if (e_table_subset_construct (table_subset
, source_model
, nvals
) == NULL
) {
615 g_object_unref (table_subset
);
619 return (ETableModel
*) table_subset
;
623 e_table_subset_get_source_model (ETableSubset
*table_subset
)
625 g_return_val_if_fail (E_IS_TABLE_SUBSET (table_subset
), NULL
);
627 return table_subset
->priv
->source_model
;
631 e_table_subset_model_to_view_row (ETableSubset
*table_subset
,
636 g_return_val_if_fail (E_IS_TABLE_SUBSET (table_subset
), -1);
638 for (i
= 0; i
< table_subset
->n_map
; i
++) {
639 if (table_subset
->map_table
[i
] == model_row
)
646 e_table_subset_view_to_model_row (ETableSubset
*table_subset
,
649 g_return_val_if_fail (E_IS_TABLE_SUBSET (table_subset
), -1);
651 if (view_row
>= 0 && view_row
< table_subset
->n_map
)
652 return table_subset
->map_table
[view_row
];
658 e_table_subset_get_toplevel (ETableSubset
*table_subset
)
660 g_return_val_if_fail (E_IS_TABLE_SUBSET (table_subset
), NULL
);
662 if (E_IS_TABLE_SUBSET (table_subset
->priv
->source_model
))
663 return e_table_subset_get_toplevel (
664 E_TABLE_SUBSET (table_subset
->priv
->source_model
));
666 return table_subset
->priv
->source_model
;
670 e_table_subset_print_debugging (ETableSubset
*table_subset
)
674 g_return_if_fail (E_IS_TABLE_SUBSET (table_subset
));
676 for (i
= 0; i
< table_subset
->n_map
; i
++) {
677 g_print ("%8d\n", table_subset
->map_table
[i
]);