1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * Copyright (C) 2006 Armin Burgmeier
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "element-editor.h"
21 #include "cell-renderer-flags.h"
23 #include <gtk/gtktreeselection.h>
24 #include <gtk/gtkcellrenderercombo.h>
25 #include <gtk/gtkcellrenderertext.h>
26 #include <gtk/gtkcellrenderer.h>
27 #include <gtk/gtkliststore.h>
28 #include <gtk/gtkentry.h>
30 typedef struct _CgElementEditorColumn CgElementEditorColumn
;
31 struct _CgElementEditorColumn
33 CgElementEditor
*parent
;
34 CgElementEditorColumnType type
;
35 GtkTreeViewColumn
*column
;
36 GtkCellRenderer
*renderer
;
39 typedef struct _CgElementEditorReference CgElementEditorReference
;
40 struct _CgElementEditorReference
42 CgElementEditorColumn
*column
;
46 typedef struct _CgElementEditorPrivate CgElementEditorPrivate
;
47 struct _CgElementEditorPrivate
53 CgElementEditorColumn
*columns
;
55 GtkButton
*add_button
;
56 GtkButton
*remove_button
;
59 #define CG_ELEMENT_EDITOR_PRIVATE(o) \
60 (G_TYPE_INSTANCE_GET_PRIVATE( \
62 CG_TYPE_ELEMENT_EDITOR, \
63 CgElementEditorPrivate \
73 static GObjectClass
*parent_class
= NULL
;
75 static CgElementEditorReference
*
76 cg_element_editor_reference_new (CgElementEditorColumn
*column
,
77 const gchar
*path_str
)
79 CgElementEditorReference
*ref
;
80 ref
= g_new (CgElementEditorReference
, 1);
83 ref
->path_str
= g_strdup (path_str
);
89 cg_element_editor_reference_free (CgElementEditorReference
*ref
)
91 g_free (ref
->path_str
);
96 cg_element_editor_select (CgElementEditor
*editor
,
100 CgElementEditorPrivate
*priv
;
101 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
103 if (column
< priv
->n_columns
)
105 gtk_widget_grab_focus (GTK_WIDGET (priv
->view
));
108 gtk_tree_view_scroll_to_cell (priv
->view
, path
,
109 priv
->columns
[column
].column
, FALSE
,
112 gtk_tree_view_set_cursor_on_cell (priv
->view
, path
,
113 priv
->columns
[column
].column
,
114 priv
->columns
[column
].renderer
,
120 cg_element_editor_edited_idle_cb (gpointer user_data
)
122 CgElementEditorReference
*ref
;
123 CgElementEditorPrivate
*priv
;
126 ref
= (CgElementEditorReference
*) user_data
;
127 priv
= CG_ELEMENT_EDITOR_PRIVATE (ref
->column
->parent
);
129 path
= gtk_tree_path_new_from_string (ref
->path_str
);
131 cg_element_editor_select (ref
->column
->parent
, path
,
132 ref
->column
- priv
->columns
);
134 gtk_tree_path_free (path
);
139 cg_element_editor_row_inserted_cb (G_GNUC_UNUSED GtkTreeModel
*model
,
141 G_GNUC_UNUSED GtkTreeIter
*iter
,
144 CgElementEditor
*editor
;
145 CgElementEditorPrivate
*priv
;
146 CgElementEditorReference
* ref
;
149 editor
= CG_ELEMENT_EDITOR (user_data
);
150 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
152 path_str
= gtk_tree_path_to_string(path
);
153 ref
= cg_element_editor_reference_new (&priv
->columns
[0], path_str
);
156 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE
,
157 cg_element_editor_edited_idle_cb
, ref
,
158 (GDestroyNotify
) cg_element_editor_reference_free
);
162 cg_element_editor_list_edited_cb (G_GNUC_UNUSED GtkCellRendererText
*renderer
,
163 const gchar
*path_str
,
167 CgElementEditorReference
*new_ref
;
168 CgElementEditorColumn
* column
;
169 CgElementEditorPrivate
*priv
;
173 column
= (CgElementEditorColumn
*) user_data
;
174 priv
= CG_ELEMENT_EDITOR_PRIVATE (column
->parent
);
176 path
= gtk_tree_path_new_from_string (path_str
);
177 gtk_tree_model_get_iter (priv
->list
, &iter
, path
);
179 gtk_list_store_set (GTK_LIST_STORE (priv
->list
), &iter
,
180 column
- priv
->columns
, text
, -1);
181 gtk_tree_path_free (path
);
183 if(column
- priv
->columns
+ 1 < priv
->n_columns
)
185 /* We do not immediately select the new column because if this entry
186 * caused the column to be resized we first want to get the resize done.
187 * Otherwise, the next editing widget would appear at the old position
188 * of the next column (before the resize of this one). */
189 new_ref
= cg_element_editor_reference_new (column
+ 1, path_str
);
190 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE
,
191 cg_element_editor_edited_idle_cb
, new_ref
,
192 (GDestroyNotify
) cg_element_editor_reference_free
);
197 cg_element_editor_string_edited_cb (G_GNUC_UNUSED GtkCellRendererText
199 const gchar
*path_str
,
203 CgElementEditorColumn
*column
;
204 CgElementEditorPrivate
*priv
;
208 column
= (CgElementEditorColumn
*) user_data
;
209 priv
= CG_ELEMENT_EDITOR_PRIVATE (column
->parent
);
211 path
= gtk_tree_path_new_from_string (path_str
);
212 gtk_tree_model_get_iter (priv
->list
, &iter
, path
);
213 gtk_tree_path_free (path
);
215 gtk_list_store_set(GTK_LIST_STORE(priv
->list
), &iter
,
216 column
- priv
->columns
, text
, -1);
220 cg_element_editor_string_activate_cb (G_GNUC_UNUSED GtkEntry
*entry
,
223 CgElementEditorPrivate
* priv
;
224 CgElementEditorReference
*ref
;
225 CgElementEditorReference
*new_ref
;
227 ref
= (CgElementEditorReference
*) user_data
;
228 priv
= CG_ELEMENT_EDITOR_PRIVATE(ref
->column
->parent
);
230 /* We do not immediately select the new column because if this entry
231 * caused the column to be resized we first want to get the resize done.
232 * Otherwise, the next editing widget would appear at the old position
233 * of the next column (before the resize of this one). */
234 if(ref
->column
- priv
->columns
+ 1 < priv
->n_columns
)
236 new_ref
= cg_element_editor_reference_new (ref
->column
+ 1,
239 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE
,
240 cg_element_editor_edited_idle_cb
, new_ref
,
241 (GDestroyNotify
) cg_element_editor_reference_free
);
246 cg_element_editor_string_editing_started_cb (G_GNUC_UNUSED
247 GtkCellRenderer
*renderer
,
248 GtkCellEditable
*editable
,
249 const gchar
*path_str
,
252 if (GTK_IS_ENTRY (editable
))
254 g_signal_connect_data (G_OBJECT (editable
), "activate",
255 G_CALLBACK (cg_element_editor_string_activate_cb
),
256 cg_element_editor_reference_new (user_data
, path_str
),
257 (GClosureNotify
) cg_element_editor_reference_free
,
263 cg_element_editor_arguments_editing_started_cb (G_GNUC_UNUSED
264 GtkCellRenderer
*renderer
,
265 GtkCellEditable
*editable
,
266 const gchar
*path_str
,
271 if (GTK_IS_ENTRY (editable
))
273 text
= gtk_entry_get_text (GTK_ENTRY (editable
));
274 if (text
== NULL
|| *text
== '\0')
276 gtk_entry_set_text (GTK_ENTRY (editable
), "()");
278 /* TODO: This does not work, although we are connected with
279 * G_CONNECT_AFTER... */
280 gtk_editable_set_position (GTK_EDITABLE (editable
), 1);
283 /* cg_element_editor_argumens_activate_cb would to exactly the same
284 * as cg_element_editor_string_activate_cb, so there is no
286 g_signal_connect_data (G_OBJECT (editable
), "activate",
287 G_CALLBACK (cg_element_editor_string_activate_cb
),
288 cg_element_editor_reference_new (user_data
, path_str
),
289 (GClosureNotify
) cg_element_editor_reference_free
,
295 cg_element_editor_add_button_clicked_cb (G_GNUC_UNUSED GtkButton
*button
,
298 CgElementEditor
*editor
;
299 CgElementEditorPrivate
*priv
;
302 editor
= CG_ELEMENT_EDITOR (user_data
);
303 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
305 gtk_list_store_append (GTK_LIST_STORE (priv
->list
), &iter
);
309 cg_element_editor_remove_button_clicked_cb (G_GNUC_UNUSED GtkButton
*button
,
312 CgElementEditor
*editor
;
313 CgElementEditorPrivate
*priv
;
314 GtkTreeSelection
*selection
;
317 GList
*selected_rows
;
318 GList
*selected_iters
;
321 editor
= CG_ELEMENT_EDITOR (user_data
);
322 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
323 selection
= gtk_tree_view_get_selection (priv
->view
);
324 selected_rows
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
325 selected_iters
= NULL
;
327 /* Convert paths to iters because changing the model borks offsets
328 * in paths, but since GtkListStore has GTK_TREE_MODEL_PERSIST set,
329 * iters continue to live after changing the model. */
330 for (cur_item
= selected_rows
; cur_item
!= NULL
; cur_item
= cur_item
->next
)
332 path
= cur_item
->data
;
333 iter
= g_new (GtkTreeIter
, 1);
335 gtk_tree_model_get_iter (priv
->list
, iter
, path
);
336 selected_iters
= g_list_prepend (selected_iters
, iter
);
338 gtk_tree_path_free (path
);
341 for (cur_item
= selected_iters
;
343 cur_item
= cur_item
->next
)
345 iter
= cur_item
->data
;
346 gtk_list_store_remove (GTK_LIST_STORE (priv
->list
), iter
);
350 g_list_free (selected_rows
);
351 g_list_free (selected_iters
);
355 cg_element_editor_selection_changed_cb (GtkTreeSelection
*selection
,
358 CgElementEditor
*editor
;
359 CgElementEditorPrivate
*priv
;
361 editor
= CG_ELEMENT_EDITOR (user_data
);
362 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
364 if (gtk_tree_selection_count_selected_rows (selection
) > 0)
365 gtk_widget_set_sensitive (GTK_WIDGET (priv
->remove_button
), TRUE
);
367 gtk_widget_set_sensitive (GTK_WIDGET (priv
->remove_button
), FALSE
);
371 cg_element_editor_init (CgElementEditor
*element_editor
)
373 CgElementEditorPrivate
*priv
;
374 priv
= CG_ELEMENT_EDITOR_PRIVATE (element_editor
);
379 priv
->columns
= NULL
;
383 cg_element_editor_finalize (GObject
*object
)
385 CgElementEditor
*element_editor
;
386 CgElementEditorPrivate
*priv
;
388 element_editor
= CG_ELEMENT_EDITOR (object
);
389 priv
= CG_ELEMENT_EDITOR_PRIVATE (element_editor
);
391 g_free (priv
->columns
);
392 if (priv
->list
!= NULL
)
393 g_object_unref (G_OBJECT (priv
->list
));
395 G_OBJECT_CLASS (parent_class
)->finalize (object
);
399 cg_element_editor_set_property (GObject
*object
,
404 CgElementEditor
*element_editor
;
405 CgElementEditorPrivate
*priv
;
407 g_return_if_fail (CG_IS_ELEMENT_EDITOR (object
));
409 element_editor
= CG_ELEMENT_EDITOR (object
);
410 priv
= CG_ELEMENT_EDITOR_PRIVATE (element_editor
);
415 priv
->view
= g_value_get_object (value
);
418 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
424 cg_element_editor_get_property (GObject
*object
,
429 CgElementEditor
*element_editor
;
430 CgElementEditorPrivate
*priv
;
432 g_return_if_fail (CG_IS_ELEMENT_EDITOR (object
));
434 element_editor
= CG_ELEMENT_EDITOR (object
);
435 priv
= CG_ELEMENT_EDITOR_PRIVATE (element_editor
);
440 g_value_set_object (value
, G_OBJECT (priv
->view
));
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
449 cg_element_editor_class_init(CgElementEditorClass
*klass
)
451 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
452 parent_class
= g_type_class_peek_parent (klass
);
454 g_type_class_add_private (klass
, sizeof (CgElementEditorPrivate
));
456 object_class
->finalize
= cg_element_editor_finalize
;
457 object_class
->set_property
= cg_element_editor_set_property
;
458 object_class
->get_property
= cg_element_editor_get_property
;
460 g_object_class_install_property(object_class
,
462 g_param_spec_object("tree-view",
464 "Tree view the element editor works on",
466 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
470 cg_element_editor_get_type (void)
472 static GType our_type
= 0;
476 static const GTypeInfo our_info
=
478 sizeof (CgElementEditorClass
),
479 (GBaseInitFunc
) NULL
,
480 (GBaseFinalizeFunc
) NULL
,
481 (GClassInitFunc
) cg_element_editor_class_init
,
484 sizeof (CgElementEditor
),
486 (GInstanceInitFunc
) cg_element_editor_init
,
490 our_type
= g_type_register_static (G_TYPE_OBJECT
, "CgElementEditor",
498 cg_element_editor_init_list_renderer(CgElementEditorColumn
*column
,
502 GtkTreeModel
*combo_list
;
506 *type
= G_TYPE_STRING
;
508 column
->renderer
= gtk_cell_renderer_combo_new ();
509 combo_list
= GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING
));
511 for (items
= va_arg (*arglist
, const gchar
**);
515 gtk_list_store_append (GTK_LIST_STORE (combo_list
), &iter
);
516 gtk_list_store_set (GTK_LIST_STORE (combo_list
), &iter
, 0, *items
, -1);
519 g_object_set(column
->renderer
, "model", combo_list
, "text-column", 0,
520 "editable", TRUE
, "has-entry", FALSE
, NULL
);
522 g_signal_connect (G_OBJECT (column
->renderer
), "edited",
523 G_CALLBACK (cg_element_editor_list_edited_cb
), column
);
525 g_object_unref (G_OBJECT (combo_list
));
529 cg_element_editor_init_flags_renderer (CgElementEditorColumn
*column
,
533 GtkTreeModel
*combo_list
;
534 const CgElementEditorFlags
*items
;
537 *type
= G_TYPE_STRING
;
539 column
->renderer
= cg_cell_renderer_flags_new ();
540 combo_list
= GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING
,
543 for (items
= va_arg (*arglist
, const CgElementEditorFlags
*);
547 gtk_list_store_append (GTK_LIST_STORE (combo_list
), &iter
);
548 gtk_list_store_set (GTK_LIST_STORE (combo_list
), &iter
,
549 0, items
->name
, 1, items
->abbrevation
, -1);
552 g_object_set (column
->renderer
, "model", combo_list
, "text-column", 0,
553 "abbrevation_column", 1, "editable", TRUE
, NULL
);
555 g_signal_connect (G_OBJECT (column
->renderer
), "edited",
556 G_CALLBACK (cg_element_editor_list_edited_cb
), column
);
558 g_object_unref (G_OBJECT (combo_list
));
562 cg_element_editor_init_string_renderer (CgElementEditorColumn
*column
,
564 G_GNUC_UNUSED
va_list *arglist
)
566 *type
= G_TYPE_STRING
;
567 column
->renderer
= gtk_cell_renderer_text_new ();
569 g_object_set (G_OBJECT (column
->renderer
), "editable", TRUE
, NULL
);
571 /* We intentionally do not only connect to the "edited" signal here
572 * because this one is also fired when the user types something in and
573 * then clicks somewhere else. In such a situation, s/he wants to continue
574 * editing somewhere else, but we would start editing the next column
577 * The "edited" signal handler does only store the new text whereas the
578 * "editing-started" signal handler connects to the "activate" signal of
579 * the resulting entry. This way, pressing enter to terminate the editing
580 * goes on to the next column, but other ways to terminate the input
582 g_signal_connect_after (G_OBJECT (column
->renderer
), "edited",
583 G_CALLBACK (cg_element_editor_string_edited_cb
),
586 g_signal_connect_after (G_OBJECT (column
->renderer
), "editing-started",
587 G_CALLBACK(cg_element_editor_string_editing_started_cb
), column
);
591 cg_element_editor_init_arguments_renderer (CgElementEditorColumn
*column
,
593 G_GNUC_UNUSED
va_list *arglist
)
595 *type
= G_TYPE_STRING
;
596 column
->renderer
= gtk_cell_renderer_text_new ();
598 g_object_set (G_OBJECT (column
->renderer
), "editable", TRUE
, NULL
);
601 g_signal_connect_after (G_OBJECT (column
->renderer
), "edited",
602 G_CALLBACK (cg_element_editor_string_edited_cb
),
605 g_signal_connect_after (G_OBJECT (column
->renderer
), "editing-started",
606 G_CALLBACK(cg_element_editor_arguments_editing_started_cb
), column
);
610 cg_element_editor_new (GtkTreeView
*view
,
611 GtkButton
*add_button
,
612 GtkButton
*remove_button
,
616 CgElementEditor
*editor
;
617 CgElementEditorPrivate
*priv
;
618 CgElementEditorColumnType column
;
619 GtkTreeSelection
*selection
;
625 editor
= CG_ELEMENT_EDITOR (g_object_new (CG_TYPE_ELEMENT_EDITOR
,
626 "tree-view", view
, NULL
));
628 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
630 types
= g_malloc (sizeof (GType
) * n_columns
);
631 priv
->n_columns
= n_columns
;
632 priv
->columns
= g_malloc (sizeof (CgElementEditorColumn
) * n_columns
);
634 va_start (arglist
, n_columns
);
635 for (i
= 0; i
< n_columns
; ++ i
)
637 priv
->columns
[i
].parent
= editor
;
639 title
= va_arg (arglist
, const gchar
*);
640 column
= va_arg (arglist
, CgElementEditorColumnType
);
641 priv
->columns
[i
].type
= column
;
643 priv
->columns
[i
].column
= gtk_tree_view_column_new ();
644 gtk_tree_view_column_set_title (priv
->columns
[i
].column
, title
);
648 case CG_ELEMENT_EDITOR_COLUMN_LIST
:
649 cg_element_editor_init_list_renderer (&priv
->columns
[i
],
650 &types
[i
], &arglist
);
652 case CG_ELEMENT_EDITOR_COLUMN_FLAGS
:
653 cg_element_editor_init_flags_renderer (&priv
->columns
[i
],
654 &types
[i
], &arglist
);
656 case CG_ELEMENT_EDITOR_COLUMN_STRING
:
657 cg_element_editor_init_string_renderer (&priv
->columns
[i
],
658 &types
[i
], &arglist
);
660 case CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS
:
661 cg_element_editor_init_arguments_renderer (&priv
->columns
[i
],
662 &types
[i
], &arglist
);
665 g_assert_not_reached ();
669 gtk_tree_view_column_pack_start (priv
->columns
[i
].column
,
670 priv
->columns
[i
].renderer
, TRUE
);
672 gtk_tree_view_append_column (view
, priv
->columns
[i
].column
);
676 priv
->list
= GTK_TREE_MODEL (gtk_list_store_newv (n_columns
, types
));
679 /* Second pass, associate attributes */
680 for (i
= 0; i
< n_columns
; ++ i
)
682 switch (priv
->columns
[i
].type
)
684 case CG_ELEMENT_EDITOR_COLUMN_LIST
:
685 case CG_ELEMENT_EDITOR_COLUMN_FLAGS
:
686 case CG_ELEMENT_EDITOR_COLUMN_STRING
:
687 case CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS
:
688 gtk_tree_view_column_add_attribute (priv
->columns
[i
].column
,
689 priv
->columns
[i
].renderer
,
694 g_assert_not_reached ();
699 g_signal_connect_after (G_OBJECT (priv
->list
), "row-inserted",
700 G_CALLBACK (cg_element_editor_row_inserted_cb
),
703 priv
->add_button
= add_button
;
704 priv
->remove_button
= remove_button
;
706 if(priv
->add_button
!= NULL
)
708 g_signal_connect (G_OBJECT(priv
->add_button
), "clicked",
709 G_CALLBACK (cg_element_editor_add_button_clicked_cb
),
713 if(priv
->remove_button
!= NULL
)
715 g_signal_connect (G_OBJECT (priv
->remove_button
), "clicked",
716 G_CALLBACK (cg_element_editor_remove_button_clicked_cb
), editor
);
719 selection
= gtk_tree_view_get_selection (view
);
720 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
722 if(priv
->remove_button
!= NULL
)
724 g_signal_connect(G_OBJECT (selection
), "changed",
725 G_CALLBACK (cg_element_editor_selection_changed_cb
),
729 gtk_tree_view_set_model (view
, priv
->list
);
734 cg_element_editor_set_valuesv_foreach_func (gpointer key
,
741 str
= (GString
*)user_data
;
742 escaped
= g_strescape ((const gchar
*) data
, NULL
);
744 g_string_append (str
, (const gchar
*) key
);
745 g_string_append (str
, "=\"");
746 g_string_append (str
, escaped
);
747 g_string_append (str
, "\";");
752 cg_element_editor_set_valuesv (CgElementEditor
*editor
,
754 NPWValueHeap
*values
,
755 CgElementEditorTransformFunc func
,
757 const gchar
**field_names
)
759 CgElementEditorPrivate
*priv
;
770 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
773 value_str
= g_string_sized_new (256);
775 for (result
= gtk_tree_model_get_iter_first (priv
->list
, &iter
);
777 result
= gtk_tree_model_iter_next (priv
->list
, &iter
))
779 value_name
= g_strdup_printf ("%s[%d]", name
, row_counter
);
781 table
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
782 NULL
, (GDestroyNotify
) g_free
);
784 for (i
= 0; i
< priv
->n_columns
; ++ i
)
786 gtk_tree_model_get (priv
->list
, &iter
, i
, &single_value
, -1);
787 g_hash_table_insert (table
, (gpointer
) field_names
[i
],
791 if(func
!= NULL
) func (table
, user_data
);
793 g_string_append_c (value_str
, '{');
794 g_hash_table_foreach (table
,
795 cg_element_editor_set_valuesv_foreach_func
,
797 g_string_append_c (value_str
, '}');
798 g_hash_table_destroy (table
);
800 value
= npw_value_heap_find_value (values
, value_name
);
802 npw_value_heap_set_value (values
, value
, value_str
->str
,
805 g_string_set_size (value_str
, 0);
811 g_string_free (value_str
, TRUE
);
815 cg_element_editor_set_values (CgElementEditor
*editor
,
817 NPWValueHeap
*values
,
818 CgElementEditorTransformFunc func
,
822 const gchar
**field_names
;
823 CgElementEditorPrivate
*priv
;
827 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
829 field_names
= g_malloc (sizeof (const gchar
*) * priv
->n_columns
);
830 va_start (arglist
, user_data
);
832 for (i
= 0; i
< priv
->n_columns
; ++ i
)
833 field_names
[i
] = va_arg (arglist
, const gchar
*);
835 cg_element_editor_set_valuesv (editor
, name
, values
, func
,
836 user_data
, field_names
);
839 g_free (field_names
);
843 cg_element_editor_set_value_count (CgElementEditor
*editor
,
845 NPWValueHeap
*values
,
846 CgElementEditorConditionFunc func
,
849 CgElementEditorPrivate
* priv
;
858 priv
= CG_ELEMENT_EDITOR_PRIVATE (editor
);
859 vals
= g_malloc (priv
->n_columns
* sizeof (const gchar
*));
862 for (result
= gtk_tree_model_get_iter_first (priv
->list
, &iter
);
864 result
= gtk_tree_model_iter_next (priv
->list
, &iter
))
866 for (i
= 0; i
< priv
->n_columns
; ++ i
)
868 gtk_tree_model_get (priv
->list
, &iter
, i
, &vals
[i
], -1);
875 else if (func (vals
, user_data
) == TRUE
)
883 sprintf (count_str
, "%u", count
);
884 value
= npw_value_heap_find_value (values
, name
);
885 npw_value_heap_set_value (values
, value
, count_str
, NPW_VALID_VALUE
);