PageRenderTime 29ms CodeModel.GetById 14ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/src/wrappers/gtk/examples/tree/tree_demo.e

http://github.com/tybor/Liberty
Specman e | 644 lines | 209 code | 101 blank | 334 comment | 8 complexity | ff65467ed6ce1f35c20fbe00d4b29d60 MD5 | raw file
  1indexing
  2	description: "Tree example translated to Eiffel from C"
  3	copyright: "Copyright (c) 2003-2004 Tim-Philipp M?ller <tim at centricular dot net>, Copyright (c) 2005, Paolo Redaelli"
  4	license: "LGPL v2 or later"
  5	date: "$Date:$"
  6	revision: "$Revision:$"
  7	original_version_url: "http://scentric.net/tutorial/treeview-tutorial.html"
  8
  9class TREE_DEMO
 10
 11	-- Tree and List Widget Overview -- Overview of GtkTreeModel,
 12	-- GtkTreeView, and other associated widgets
 13
 14	-- Overview: To create a tree or list in GTK+, use the GtkTreeModel
 15	-- interface in conjunction with the GtkTreeView widget. This
 16	-- widget is designed around a Model/View/Controller design and
 17	-- consists of four major parts:
 18
 19	--   The tree view widget (GtkTreeView)
 20	--   The view column (GtkTreeViewColumn)
 21	--   The cell renderers (GtkCellRenderer etc.)
 22	--   The model interface (GtkTreeModel)
 23	
 24	-- The View is composed of the first three objects, while the last
 25	-- is the Model. One of the prime benefits of the MVC design is
 26	-- that multiple views can be created of a single model. For
 27	-- example, a model mapping the file system could be created for a
 28	-- file manager. Many views could be created to display various
 29	-- parts of the file system, but only one copy need be kept in
 30	-- memory.
 31
 32	-- The purpose of the cell renderers is to provide extensibility to
 33	-- the widget and to allow multiple ways of rendering the same type
 34	-- of data. For example, consider how to render a boolean
 35	-- variable. Should it render it as a string of "True" or "False",
 36	-- "On" or "Off", or should it be rendered as a checkbox?
 37	
 38	-- Creating a model: GTK+ provides two simple models that can be
 39	-- used: the GtkListStore and the GtkTreeStore. GtkListStore is
 40	-- used to model list widgets, while the GtkTreeStore models
 41	-- trees. It is possible to develop a new type of model, but the
 42	-- existing models should be satisfactory for all but the most
 43	-- specialized of situations. Creating the model is quite simple:
 44	
 45	-- GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING,
 46	-- G_TYPE_BOOLEAN);
 47	
 48	-- This creates a list store with two columns: a string column and
 49	-- a boolean column. Typically the 2 is never passed directly like
 50	-- that; usually an enum is created wherein the different columns
 51	-- are enumerated, followed by a token that represents the total
 52	-- number of columns. The next example will illustrate this, only
 53	-- using a tree store instead of a list store. Creating a tree
 54	-- store operates almost exactly the same.
 55	
 56	-- enum
 57	-- {
 58	--    TITLE_COLUMN,
 59	--    AUTHOR_COLUMN,
 60	--    CHECKED_COLUMN,
 61	--    N_COLUMNS
 62	-- };
 63	--
 64	-- GtkTreeStore *store = gtk_tree_store_new (N_COLUMNS,       /* Total number of columns */
 65	--                                           G_TYPE_STRING,   /* Book title              */
 66	--                                           G_TYPE_STRING,   /* Author                  */
 67	--                                           G_TYPE_BOOLEAN); /* Is checked out?         */
 68
 69	-- Adding data to the model is done using gtk_tree_store_set() or
 70	-- gtk_list_store_set(), depending upon which sort of model was
 71	-- created. To do this, a GtkTreeIter must be acquired. The
 72	-- iterator points to the location where data will be added.
 73
 74	-- Once an iterator has been acquired, gtk_tree_store_set() is used
 75	-- to apply data to the part of the model that the iterator points
 76	-- to. Consider the following example:
 77
 78	-- GtkTreeIter   iter;
 79	--
 80	-- gtk_tree_store_append (store, &iter, NULL);  /* Acquire an iterator */
 81	--
 82	-- gtk_tree_store_set (store, &iter,
 83	--                     TITLE_COLUMN, "The Principle of Reason",
 84	--                     AUTHOR_COLUMN, "Martin Heidegger",
 85	--                     CHECKED_COLUMN, FALSE,
 86	--                     -1);
 87
 88	-- Notice that the last argument is -1. This is always done because
 89	-- this is a variable-argument function and it needs to know when
 90	-- to stop processing arguments. It can be used to set the data in
 91	-- any or all columns in a given row.
 92
 93	-- The third argument to gtk_tree_store_append() is the parent
 94	-- iterator. It is used to add a row to a GtkTreeStore as a child
 95	-- of an existing row. This means that the new row will only be
 96	-- visible when its parent is visible and in its expanded
 97	-- state. Consider the following example:
 98
 99	-- GtkTreeIter iter1;  /* Parent iter */
100	-- GtkTreeIter iter2;  /* Child iter  */
101	--
102	-- gtk_tree_store_append (store, &iter1, NULL);  /* Acquire a top-level iterator */
103	-- gtk_tree_store_set (store, &iter1,
104	--                     TITLE_COLUMN, "The Art of Computer Programming",
105	--                     AUTHOR_COLUMN, "Donald E. Knuth",
106	--                     CHECKED_COLUMN, FALSE,
107	--                     -1);
108	--
109	-- gtk_tree_store_append (store, &iter2, &iter1);  /* Acquire a child iterator */
110	-- gtk_tree_store_set (store, &iter2,
111	--                     TITLE_COLUMN, "Volume 1: Fundamental Algorithms",
112	--                     -1);
113	--
114	-- gtk_tree_store_append (store, &iter2, &iter1);
115	-- gtk_tree_store_set (store, &iter2,
116	--                     TITLE_COLUMN, "Volume 2: Seminumerical Algorithms",
117	--                     -1);
118	--
119	-- gtk_tree_store_append (store, &iter2, &iter1);
120	-- gtk_tree_store_set (store, &iter2,
121	--                     TITLE_COLUMN, "Volume 3: Sorting and Searching",
122	--                     -1);
123
124	-- Creating the view component: While there are several different
125	-- models to choose from, there is only one view widget to deal
126	-- with. It works with either the list or the tree store.  Setting
127	-- up a GtkTreeView is not a difficult matter. It needs a
128	-- GtkTreeModel to know where to retrieve its data from.
129
130	-- GtkWidget *tree;
131	--
132	-- tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
133
134	-- Columns and cell renderers: Once the GtkTreeView widget has a
135	-- model, it will need to know how to display the model. It does
136	-- this with columns and cell renderers.
137
138	-- Cell renderers are used to draw the data in the tree model in a
139	-- way. There are a number of cell renderers that come with GTK+
140	-- 2.x, including the GtkCellRendererText, GtkCellRendererPixbuf
141	-- and the GtkCellRendererToggle.  It is relatively easy to write a
142	-- custom renderer.
143
144	-- A GtkTreeViewColumn is the object that GtkTreeView uses to
145	-- organize the vertical columns in the tree view. It needs to know
146	-- the name of the column to label for the user, what type of cell
147	-- renderer to use, and which piece of data to retrieve from the
148	-- model for a given row.
149
150	-- GtkCellRenderer *renderer;
151	-- GtkTreeViewColumn *column;
152	--
153	-- renderer = gtk_cell_renderer_text_new ();
154	-- column = gtk_tree_view_column_new_with_attributes ("Author",
155	--                                                    renderer,
156	--                                                    "text", AUTHOR_COLUMN,
157	--                                                    NULL);
158	-- gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
159	--
160	--   At this point, all the steps in creating a displayable tree have been
161	--   covered. The model is created, data is stored in it, a tree view is
162	--   created and columns are added to it.
163	--
164	--   --------------------------------------------------------------------------
165	--
166	-- Selection handling: Most applications will need to not only deal with displaying data, but
167	--   also receiving input events from users. To do this, simply get a reference
168	--   to a selection object and connect to the "changed" signal.
169
170	-- /* Prototype for selection handler callback */
171	-- static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
172	--
173	-- /* Setup the selection handler */
174	-- GtkTreeSelection *select;
175	--
176	-- select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
177	-- gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
178	-- g_signal_connect (G_OBJECT (select), "changed",
179	--                   G_CALLBACK (tree_selection_changed_cb),
180	--                   NULL);
181
182	--   Then to retrieve data for the row selected:
183
184	-- static void
185	-- tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
186	-- {
187	--         GtkTreeIter iter;
188	--         GtkTreeModel *model;
189	--         gchar *author;
190	--
191	--         if (gtk_tree_selection_get_selected (selection, &model, &iter))
192	--         {
193	--                 gtk_tree_model_get (model, &iter, AUTHOR_COLUMN, &author, -1);
194	--
195	--                 g_print ("You selected a book by <link linkend="s"><literal>s</literal></link>\n", author);
196	--
197	--                 g_free (author);
198	--         }
199	-- }
200
201	-- Simple Example: Here is a simple example of using a GtkTreeView
202	-- widget in context of the other widgets. It simply creates a
203	-- simple model and view, and puts them together. Note that the
204	-- model is never populated with data - that is left as an exercise
205	-- for the reader. More information can be found on this in the
206	-- GtkTreeModel section.
207
208	-- enum
209	-- {
210	--    TITLE_COLUMN,
211	--    AUTHOR_COLUMN,
212	--    CHECKED_COLUMN,
213	--    N_COLUMNS
214	-- };
215	--
216	-- void
217	-- setup_tree (void)
218	-- {
219	--    GtkTreeStore *store;
220	--    GtkWidget *tree;
221	--    GtkTreeViewColumn *column;
222	--    GtkCellRenderer *renderer;
223	--
224	--    /* Create a model.  We are using the store model for now, though we
225	--     * could use any other GtkTreeModel */
226	--    store = gtk_tree_store_new (N_COLUMNS,
227	--                                G_TYPE_STRING,
228	--                                G_TYPE_STRING,
229	--                                G_TYPE_BOOLEAN);
230	--
231	--    /* custom function to fill the model with data */
232	--    populate_tree_model (store);
233	--
234	--    /* Create a view */
235	--    tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
236	--
237	--    /* The view now holds a reference.  We can get rid of our own
238	--     * reference */
239	--    g_object_unref (G_OBJECT (store));
240	--
241	--    /* Create a cell render and arbitrarily make it red for demonstration
242	--     * purposes */
243	--    renderer = gtk_cell_renderer_text_new ();
244	--    g_object_set (G_OBJECT (renderer),
245	--                  "foreground", "red",
246	--                  NULL);
247	--
248	--    /* Create a column, associating the "text" attribute of the
249	--     * cell_renderer to the first column of the model */
250	--    column = gtk_tree_view_column_new_with_attributes ("Author", renderer,
251	--                                                       "text", AUTHOR_COLUMN,
252	--                                                       NULL);
253	--
254	--    /* Add the column to the view. */
255	--    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
256	--
257	--    /* Second column.. title of the book. */
258	--    renderer = gtk_cell_renderer_text_new ();
259	--    column = gtk_tree_view_column_new_with_attributes ("Title",
260	--                                                       renderer,
261	--                                                       "text", TITLE_COLUMN,
262	--                                                       NULL);
263	--    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
264	--
265	--    /* Last column.. whether a book is checked out. */
266	--    renderer = gtk_cell_renderer_toggle_new ();
267	--    column = gtk_tree_view_column_new_with_attributes ("Checked out",
268	--                                                       renderer,
269	--                                                       "active", CHECKED_COLUMN,
270	--                                                       NULL);
271	--    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
272	--
273	--    /* Now we can manipulate the view just like any other GTK widget */
274	--    ...
275	-- }
276	--
277
278insert
279	GTK -- to initialize the Gimp ToolKit
280	G_TYPES
281		-- TODO: This class is necessary when creating GTK_LIST_STOREs,
282		-- since it requires explicit reference to g_type_*; it's ugly,
283		-- or better it feels mostly unEiffelish to me. Paolo 2005-06-12
284	
285	WRAPPER_HANDLER -- required to check for some bug in the
286		-- implementation and accessing wrappers' handles
287	
288	GTK_STOCK_ITEMS
289	
290	GLIB_MESSAGE_LOGGING
291
292	GDK_TYPE_EXTERNALS -- To store GDK_PIXMAPS into the store. TODO:
293			-- give the end-user a better interface.
294	
295creation make
296	
297feature -- Columns
298	name_column_n: INTEGER is 0
299	nick_column_n: INTEGER is 1
300	flag_column_n: INTEGER is 1
301	columns_n: INTEGER is 3
302
303feature
304	developers: FAST_ARRAY[TUPLE[STRING,STRING]] is
305		once
306			Result:= {FAST_ARRAY[TUPLE[STRING,STRING]]
307			<< ["Pierre-Nicolas", "eif_pini"],
308				["Anthony Lenton", "elachuni"],
309				["jose bollo", "jobo"],
310				["Natalia B. Bidart", "nessa"],
311				["Oliver Elphick", "oliver_elphick"],
312				["Raphael Mack", "ramack"],
313				["Daniel F Moisset", "trixx"]
314				["Paolo Redaelli", "tybor"],
315				["Walter Alini", "walteralini"] >>
316		}
317		end
318
319feature 
320	model: GTK_TREE_STORE is
321			-- tree model with some data set
322		local
323			top_level, child: GTK_TREE_ITER
324
325			developer_iter: ITERATOR[TUPLE[STRING,STRING]]
326		once 
327			create Result.make (<<g_type_string, g_type_string, gdk_type_pixbuf>>)
328			-- TODO: change design to remove explicit reference to g_type_*; it's
329			-- ugly, or better it feels mostly unEiffelish to me. Paolo 2005-06-01
330			
331			create top_level.make_from_model (Result)
332			create child.make_from_model (Result)
333
334			-- Append an empty top-level row to the tree store.
335			-- Top_Level will point to the new row
336			Result.append (top_level, Void)
337			Result.set_string (top_level, name_column_n, "ISE developers")
338			
339			-- Append another empty top-level row to the tree store.
340			-- Top_Level will point to the new row 
341			Result.append(top_level, Void)
342			Result.set_string (top_level, name_column_n, "SmartEiffel developers")
343
344			-- Append a child to the row we just added.
345			-- Child will point to the new row
346			Result.append(top_level, Void)
347			Result.set_string (top_level, name_column_n, "Eiffel-libraries developers")
348
349			-- Get the first row, and add a child to it as well (could
350			-- have been done right away earlier of course, this is just
351			-- for demonstration purposes)
352			
353			child := Result.get_iterator_first
354			if child = Void then
355				glib_error("Oops, we should have a first row in the tree store!\n")
356			else
357				developer_iter := developers.get_new_iterator
358				from developer_iter.start
359				until developer_iter.is_off
360				loop
361					Result.append (child, top_level)
362
363					Result.set_string (child, name_column_n, developer_iter.item.item_1)
364					Result.set_string (child, nick_column_n, developer_iter.item.item_2)
365
366					developer_iter.next
367				end
368			end
369		end
370	
371	text_renderer, flag_renderer: GTK_CELL_RENDERER
372
373	name_column, nick_column, nationality_column: GTK_TREE_VIEW_COLUMN
374
375	view: GTK_TREE_VIEW is
376		once
377			create {GTK_CELL_RENDERER_TEXT} text_renderer.make
378			create {GTK_CELL_RENDERER_PIXBUF} flag_renderer.make
379			
380			create name_column.make
381			name_column.set_title ("Name")
382			name_column.pack_start (text_renderer, True)
383			name_column.add_attribute (text_renderer, "text", name_column_n)
384												
385			create nick_column.make
386			nick_column.set_title ("Nick")
387			nick_column.pack_start (text_renderer, True)
388			nick_column.add_attribute (text_renderer, "text", nick_column_n)
389
390			create nationality_column.make
391			nick_column.set_title ("Nationality")
392			nick_column.pack_start (text_renderer, True)
393			nick_column.pack_start (flag_renderer, True)
394			nick_column.add_attribute (text_renderer, "text", flag_column_n)
395			
396			
397			create Result.make
398			Result.insert_column (name_column, name_column_n)
399			Result.insert_column (nick_column, nick_column_n)
400			
401			Result.set_model (model)
402
403			-- TODO: Original C example here insert a g_object_unref
404			-- (model); /* destroy model automatically with view */ I'm
405			-- not sure, but it shouldn't be necessary. Shall we insert
406			-- it? Paolo 2005-06-12
407		end
408
409	window: GTK_WINDOW
410
411	vbox: GTK_VBOX
412
413	button_box: GTK_HBOX
414
415	add_button, remove_button, quit_button: GTK_BUTTON
416	
417feature {}  -- Creation
418	
419	make is
420			-- Run the demo
421		local selection: GTK_TREE_SELECTION
422		do
423			gtk.initialize_gtk
424						
425			-- Create a GTK window toplevel window
426			create window.make
427			window.set_title (window_title)
428
429			-- It is a good idea to do this for all windows
430			window.connect_agent_to_destroy_signal (agent on_destroy)
431
432			view.show
433
434			create add_button.from_stock (gtk_stock_add)
435			create remove_button.from_stock (gtk_stock_remove)
436			create quit_button.from_stock (gtk_stock_quit)
437			create button_box.make(False,0) -- i.e. unhomogeneous, no spacing
438			button_box.add(add_button)
439			button_box.add(remove_button)
440			button_box.add(quit_button)
441
442			add_button.connect_agent_to_clicked_signal (agent add_clicked)
443			remove_button.connect_agent_to_clicked_signal (agent remove_clicked)
444			quit_button.connect_agent_to_clicked_signal (agent quit_clicked)
445
446			create vbox.make(False,0) -- i.e. unhomogeneous, no spacing
447			vbox.add(view)
448			vbox.add(button_box)
449			
450			window.add (vbox)
451			window.show_all
452
453			selection := view.selection
454			selection.set_single_mode
455			selection.set_select_function (agent on_select)
456			gtk.run_main_loop
457		end
458
459feature
460	traverse_model is
461		require valid_model: model /= Void
462		local iter:  GTK_TREE_ITER
463		do
464			print ("Iterating over names%N")
465			create iter.make_from_model (model)	  
466			from iter.start
467			until not iter.is_valid
468			loop -- print each name ...
469				print (model.value (iter, name_column_n).string)
470				-- Note: Is "model.value" clear enough or "model.value_at" would be clearer?
471				iter.next -- Move to next row
472				if iter.is_valid then print (", ")
473				else print ("%N")
474				end
475			end
476		end
477	
478	paths_demo is
479		local path: GTK_TREE_PATH
480		do
481			print ("Tree paths demo:%N")
482			create path.make_first
483			print ("First: ") print (path.to_string) print ("%N")
484			create path.from_string ("1:3:2")
485			print ("From string: ") print (path.to_string) print ("%N")
486		end
487
488feature -- Agents
489	add_clicked (a_button: GTK_BUTTON) is
490		do
491
492		end
493
494	remove_clicked (a_button: GTK_BUTTON) is
495		do
496			
497		end
498
499	quit_clicked (a_button: GTK_BUTTON) is
500		do
501			window.destroy
502		end
503
504	on_destroy (a_gtk_object: GTK_OBJECT) is
505		do
506			print ("Tree demo is quitting.%N")
507			paths_demo
508			print ("Traversing model:%N")
509			traverse_model
510			print ("Using GTK_TREE_MODEL.for_each to print its content:%N")
511			print ("TODO: in tree_demo on_destroy model.for_each (agent print_person)%N")
512			print ("If GTK_TREE_MODEL.for_each is implemented correctly you should see above each person's name and age.%N")
513			gtk.quit
514		end
515
516	print_person (a_model: GTK_TREE_MODEL; a_path: GTK_TREE_PATH; an_iter: GTK_TREE_ITER): BOOLEAN is
517		do
518			check	right_model: a_model = model end
519			print ("Person (code: ")
520			print (a_path.to_string) print (") name '")
521			print (a_model.value_at (an_iter, name_column_n).string)
522			print ("' nick ")
523			print (a_model.value_at (an_iter, nick_column_n).natural.out)
524			print ("%N")
525			Result := False -- i.e. go on
526		end
527			
528	on_select (a_selection: GTK_TREE_SELECTION; a_model: GTK_TREE_MODEL; a_path: GTK_TREE_PATH; path_selected: BOOLEAN): BOOLEAN is
529		do
530			if a_selection.is_node_selected then
531				print ("A selected row is being de-selected. Disabling buttons.%N")				
532				add_button.set_sensitive(False)
533				remove_button.set_sensitive(False)
534			else
535				print ("A de-selected row is being selected. Enabling buttons.%N")
536				add_button.set_sensitive(True)
537				remove_button.set_sensitive(True)
538			end
539			
540			print ("Path '") print (a_path.to_string)
541			if path_selected then print ("' is being selected")
542			else print ("' is being de-selected")
543			end
544			
545			debug
546				if a_model = Void 
547				 then print ("; no model passed but we're sure that out GTK_LIST_STORE at"+model.to_pointer.out+" has handle="+model.handle.out)
548				else print (".")
549				end
550			end
551			print ("%N")
552			Result := True -- i.e. effectively select the picked button.
553		end
554								
555feature -- Constants
556	window_title: STRING is "GTK Trees!"
557			-- Text top level window title
558end
559
560-- Examples from C docs.
561
562-- To help show some common operation of a model, some examples are
563-- provided. The first example shows three ways of getting the iter at
564-- the location "3:2:5". While the first method shown is easier, the
565-- second is much more common, as you often get paths from callbacks.
566
567-- Example 1. Acquiring a GtkTreeIter
568
569-- /* Three ways of getting the iter pointing to the location
570--  */
571-- {
572--   GtkTreePath *path;
573--   GtkTreeIter iter;
574--   GtkTreeIter parent_iter;
575
576--   /* get the iterator from a string */
577--   gtk_tree_model_get_iter_from_string (model, &iter, "3:2:5");
578
579--   /* get the iterator from a path */
580--   path = gtk_tree_path_new_from_string ("3:2:5");
581--   gtk_tree_model_get_iter (model, &iter, path);
582--   gtk_tree_path_free (path);
583
584
585--   /* walk the tree to find the iterator */
586--   gtk_tree_model_iter_nth_child (model, &iter, NULL, 3);
587--   parent_iter = iter;
588--   gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, 2);
589--   parent_iter = iter;
590--   gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, 5);
591-- }
592
593-- This second example shows a quick way of iterating through a list
594-- and getting a string and an integer from each row. The
595-- populate_model function used below is not shown, as it is specific
596-- to the GtkListStore. For information on how to write such a
597-- function, see the GtkListStore documentation.
598
599-- Example 2. Reading data from a GtkTreeModel
600
601-- enum
602-- {
603--   STRING_COLUMN,
604--   INT_COLUMN,
605--   N_COLUMNS
606-- };
607
608-- {
609--   GtkTreeModel *list_store;
610--   GtkTreeIter iter;
611--   gboolean valid;
612--   gint row_count = 0;
613
614--   /* make a new list_store */
615--   list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
616
617--   /* Fill the list store with data */
618--   populate_model (list_store);
619
620--   /* Get the first iter in the list */
621--   valid = gtk_tree_model_get_iter_first (list_store, &iter);
622
623--   while (valid)
624--     {
625--       /* Walk through the list, reading each row */
626--       gchar *str_data;
627--       gint   int_data;
628
629--       /* Make sure you terminate calls to gtk_tree_model_get()
630--        * with a '-1' value
631--        */
632--       gtk_tree_model_get (list_store, &iter, 
633--                           STRING_COLUMN, &str_data,
634--                           INT_COLUMN, &int_data,
635--                           -1);
636
637--       /* Do something with the data */
638--       g_print ("Row %d: (%s,%d)\n", row_count, str_data, int_data);
639--       g_free (str_data);
640
641--       row_count ++;
642--       valid = gtk_tree_model_iter_next (list_store, &iter);
643--     }
644-- }