1 /*
2  * Copyright (C) 2008 Tristan Van Berkom.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Authors:
19  *   Tristan Van Berkom <tvb@gnome.org>
20  */
21 
22 #include <config.h>
23 #include <glib/gi18n-lib.h>
24 #include "glade.h"
25 #include "gladeui-enum-types.h"
26 
27 #include "glade-editor-table.h"
28 
29 
30 #define BLOCK_NAME_ENTRY_CB(table)					\
31 	do { if (table->priv->name_entry)					\
32 			g_signal_handlers_block_by_func (G_OBJECT (table->priv->name_entry), \
33 							 G_CALLBACK (widget_name_edited), table); \
34 	} while (0);
35 
36 #define UNBLOCK_NAME_ENTRY_CB(table)					\
37 	do { if (table->priv->name_entry)					\
38 			g_signal_handlers_unblock_by_func (G_OBJECT (table->priv->name_entry), \
39 							   G_CALLBACK (widget_name_edited), table); \
40 	} while (0);
41 
42 
43 
44 static void glade_editor_table_init          (GladeEditorTable * self);
45 static void glade_editor_table_class_init    (GladeEditorTableClass * klass);
46 
47 static void glade_editor_table_dispose       (GObject         *object);
48 static void glade_editor_table_set_property  (GObject         *object,
49 					      guint            prop_id,
50 					      const GValue    *value,
51 					      GParamSpec      *pspec);
52 
53 static void glade_editor_table_editable_init (GladeEditableIface * iface);
54 static void glade_editor_table_realize       (GtkWidget * widget);
55 static void glade_editor_table_grab_focus    (GtkWidget * widget);
56 
57 static void append_name_field (GladeEditorTable   *table);
58 static void append_items      (GladeEditorTable   *table,
59 			       GladeWidgetAdaptor *adaptor,
60 			       GladeEditorPageType type);
61 
62 
63 struct _GladeEditorTablePrivate
64 {
65   GladeWidgetAdaptor *adaptor; /* The GladeWidgetAdaptor this
66 				* table was created for.
67 				*/
68 
69   GladeWidget *loaded_widget; /* A pointer to the currently loaded GladeWidget
70 			       */
71 
72   GtkWidget *name_label; /* A pointer to the "Name:" label (for show/hide) */
73   GtkWidget *name_entry; /* A pointer to the gtk_entry that holds
74 			  * the name of the widget. This is the
75 			  * first item _pack'ed to the table_widget.
76 			  * We have a pointer here because it is an
77 			  * entry which will not be created from a
78 			  * GladeProperty but rather from code.
79 			  */
80   GtkWidget *composite_check; /* A pointer to the composite check button */
81   GtkWidget *name_field; /* A box containing the name entry and composite check */
82 
83   GList *properties; /* A list of GladeEditorPropery items.
84 		      * For each row in the gtk_table, there is a
85 		      * corrsponding GladeEditorProperty struct.
86 		      */
87 
88   GladeEditorPageType type; /* Is this table to be used in the common tab, ?
89 			     * the general tab, a packing tab or the query popup ?
90 			     */
91 
92   gint rows;
93 
94   gboolean show_name;
95 };
96 
97 enum {
98   PROP_0,
99   PROP_PAGE_TYPE,
100 };
101 
102 G_DEFINE_TYPE_WITH_CODE (GladeEditorTable, glade_editor_table, GTK_TYPE_GRID,
103                          G_ADD_PRIVATE (GladeEditorTable)
104                          G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE,
105                                                 glade_editor_table_editable_init));
106 
107 static void
glade_editor_table_class_init(GladeEditorTableClass * klass)108 glade_editor_table_class_init (GladeEditorTableClass *klass)
109 {
110   GObjectClass *object_class = G_OBJECT_CLASS (klass);
111   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
112 
113   object_class->dispose = glade_editor_table_dispose;
114   object_class->set_property = glade_editor_table_set_property;
115 
116   widget_class->realize = glade_editor_table_realize;
117   widget_class->grab_focus = glade_editor_table_grab_focus;
118 
119   g_object_class_install_property
120       (object_class, PROP_PAGE_TYPE,
121        g_param_spec_enum ("page-type", _("Page Type"),
122 			  _("The editor page type to create this GladeEditorTable for"),
123 			  GLADE_TYPE_EDITOR_PAGE_TYPE, GLADE_PAGE_GENERAL,
124 			  G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
125 }
126 
127 static void
glade_editor_table_init(GladeEditorTable * self)128 glade_editor_table_init (GladeEditorTable *self)
129 {
130   self->priv = glade_editor_table_get_instance_private (self);
131 
132   gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
133                                   GTK_ORIENTATION_VERTICAL);
134   gtk_grid_set_row_spacing (GTK_GRID (self), 2);
135   gtk_grid_set_column_spacing (GTK_GRID (self), 6);
136 
137   /* Show name by default */
138   self->priv->show_name = TRUE;
139 }
140 
141 static void
glade_editor_table_dispose(GObject * object)142 glade_editor_table_dispose (GObject *object)
143 {
144   GladeEditorTable *table = GLADE_EDITOR_TABLE (object);
145 
146   table->priv->properties = (g_list_free (table->priv->properties), NULL);
147 
148   /* the entry is finalized anyway, just avoid setting
149    * text in it from _load();
150    */
151   table->priv->name_entry = NULL;
152 
153   glade_editable_load (GLADE_EDITABLE (table), NULL);
154 
155   G_OBJECT_CLASS (glade_editor_table_parent_class)->dispose (object);
156 }
157 
158 static void
glade_editor_table_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)159 glade_editor_table_set_property (GObject         *object,
160 				 guint            prop_id,
161 				 const GValue    *value,
162 				 GParamSpec      *pspec)
163 {
164   GladeEditorTable *table = GLADE_EDITOR_TABLE (object);
165 
166   switch (prop_id)
167     {
168     case PROP_PAGE_TYPE:
169       table->priv->type = g_value_get_enum (value);
170       break;
171     default:
172       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
173       break;
174     }
175 }
176 
177 static void
glade_editor_table_realize(GtkWidget * widget)178 glade_editor_table_realize (GtkWidget *widget)
179 {
180   GladeEditorTable *table = GLADE_EDITOR_TABLE (widget);
181   GList *list;
182   GladeEditorProperty *property;
183 
184   GTK_WIDGET_CLASS (glade_editor_table_parent_class)->realize (widget);
185 
186   /* Sync up properties, even if widget is NULL */
187   for (list = table->priv->properties; list; list = list->next)
188     {
189       property = list->data;
190       glade_editor_property_load_by_widget (property, table->priv->loaded_widget);
191     }
192 }
193 
194 static void
glade_editor_table_grab_focus(GtkWidget * widget)195 glade_editor_table_grab_focus (GtkWidget *widget)
196 {
197   GladeEditorTable *editor_table = GLADE_EDITOR_TABLE (widget);
198 
199   if (editor_table->priv->name_entry &&
200       gtk_widget_get_mapped (editor_table->priv->name_entry))
201     gtk_widget_grab_focus (editor_table->priv->name_entry);
202   else if (editor_table->priv->properties)
203     gtk_widget_grab_focus (GTK_WIDGET (editor_table->priv->properties->data));
204   else
205     GTK_WIDGET_CLASS (glade_editor_table_parent_class)->grab_focus (widget);
206 }
207 
208 static void
widget_name_edited(GtkWidget * editable,GladeEditorTable * table)209 widget_name_edited (GtkWidget *editable, GladeEditorTable *table)
210 {
211   GladeWidget *widget;
212   gchar *new_name;
213 
214   g_return_if_fail (GTK_IS_EDITABLE (editable));
215   g_return_if_fail (GLADE_IS_EDITOR_TABLE (table));
216 
217   if (table->priv->loaded_widget == NULL)
218     {
219       g_warning ("Name entry edited with no loaded widget in editor %p!\n",
220                  table);
221       return;
222     }
223 
224   widget = table->priv->loaded_widget;
225   new_name = gtk_editable_get_chars (GTK_EDITABLE (editable), 0, -1);
226 
227   if (new_name == NULL || new_name[0] == '\0')
228     {
229       /* If we are explicitly trying to set the widget name to be empty,
230        * then we must not allow it there are any active references to
231        * the widget which would otherwise break.
232        *
233        * Otherwise, we need to allocate a new unnamed prefix name for the widget
234        */
235       if (!glade_widget_has_prop_refs (widget))
236 	{
237 	  gchar *unnamed_name = glade_project_new_widget_name (glade_widget_get_project (widget), NULL, GLADE_UNNAMED_PREFIX);
238 	  glade_command_set_name (widget, unnamed_name);
239 	  g_free (unnamed_name);
240 	}
241     }
242   else if (glade_project_available_widget_name (glade_widget_get_project (widget),
243 						widget, new_name))
244     glade_command_set_name (widget, new_name);
245 
246   g_free (new_name);
247 }
248 
249 static void
widget_composite_toggled(GtkToggleButton * composite_check,GladeEditorTable * table)250 widget_composite_toggled (GtkToggleButton  *composite_check,
251 			  GladeEditorTable *table)
252 {
253   GladeProject *project;
254 
255   if (table->priv->loaded_widget == NULL)
256     {
257       g_warning ("Name entry edited with no loaded widget in editor %p!\n",
258                  table);
259       return;
260     }
261 
262   project = glade_widget_get_project (table->priv->loaded_widget);
263 
264   if (project)
265     {
266       if (gtk_toggle_button_get_active (composite_check))
267 	glade_command_set_project_template (project, table->priv->loaded_widget);
268       else
269 	glade_command_set_project_template (project, NULL);
270     }
271 }
272 
273 static void
widget_name_changed(GladeWidget * widget,GParamSpec * pspec,GladeEditorTable * table)274 widget_name_changed (GladeWidget      *widget,
275                      GParamSpec       *pspec,
276 		     GladeEditorTable *table)
277 {
278   if (!gtk_widget_get_mapped (GTK_WIDGET (table)))
279     return;
280 
281   if (table->priv->name_entry)
282     {
283       BLOCK_NAME_ENTRY_CB (table);
284 
285       if (glade_widget_has_name (table->priv->loaded_widget))
286 	gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), glade_widget_get_name (table->priv->loaded_widget));
287       else
288 	gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
289 
290       UNBLOCK_NAME_ENTRY_CB (table);
291     }
292 }
293 
294 static void
widget_composite_changed(GladeWidget * widget,GParamSpec * pspec,GladeEditorTable * table)295 widget_composite_changed (GladeWidget      *widget,
296 			  GParamSpec       *pspec,
297 			  GladeEditorTable *table)
298 {
299   if (!gtk_widget_get_mapped (GTK_WIDGET (table)))
300     return;
301 
302   if (table->priv->name_label)
303     gtk_label_set_text (GTK_LABEL (table->priv->name_label),
304 			glade_widget_get_is_composite (table->priv->loaded_widget) ?
305 			_("Class Name:") : _("ID:"));
306 
307   if (table->priv->composite_check)
308     {
309       g_signal_handlers_block_by_func (G_OBJECT (table->priv->composite_check),
310 				       G_CALLBACK (widget_composite_toggled), table);
311       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (table->priv->composite_check),
312 				    glade_widget_get_is_composite (table->priv->loaded_widget));
313       g_signal_handlers_unblock_by_func (G_OBJECT (table->priv->composite_check),
314 					 G_CALLBACK (widget_composite_toggled), table);
315     }
316 }
317 
318 static void
widget_finalized(GladeEditorTable * table,GladeWidget * where_widget_was)319 widget_finalized (GladeEditorTable *table, GladeWidget *where_widget_was)
320 {
321   table->priv->loaded_widget = NULL;
322 
323   glade_editable_load (GLADE_EDITABLE (table), NULL);
324 }
325 
326 
327 static void
glade_editor_table_load(GladeEditable * editable,GladeWidget * widget)328 glade_editor_table_load (GladeEditable *editable, GladeWidget *widget)
329 {
330   GladeEditorTable *table = GLADE_EDITOR_TABLE (editable);
331   GladeEditorProperty *property;
332   GList *list;
333 
334   /* Setup the table the first time the widget is loaded */
335   if (widget && table->priv->adaptor == NULL)
336     {
337       table->priv->adaptor = glade_widget_get_adaptor (widget);
338 
339       if (table->priv->type == GLADE_PAGE_GENERAL)
340 	append_name_field (table);
341 
342       append_items (table, table->priv->adaptor, table->priv->type);
343     }
344 
345   /* abort mission */
346   if (table->priv->loaded_widget == widget)
347     return;
348 
349   if (table->priv->loaded_widget)
350     {
351       g_signal_handlers_disconnect_by_func (G_OBJECT (table->priv->loaded_widget),
352                                             G_CALLBACK (widget_name_changed),
353                                             table);
354       g_signal_handlers_disconnect_by_func (G_OBJECT (table->priv->loaded_widget),
355                                             G_CALLBACK (widget_composite_changed),
356                                             table);
357 
358       /* The widget could die unexpectedly... */
359       g_object_weak_unref (G_OBJECT (table->priv->loaded_widget),
360                            (GWeakNotify) widget_finalized, table);
361     }
362 
363   table->priv->loaded_widget = widget;
364 
365   BLOCK_NAME_ENTRY_CB (table);
366 
367   if (table->priv->loaded_widget)
368     {
369       g_signal_connect (G_OBJECT (table->priv->loaded_widget), "notify::name",
370                         G_CALLBACK (widget_name_changed), table);
371 
372       g_signal_connect (G_OBJECT (table->priv->loaded_widget), "notify::composite",
373                         G_CALLBACK (widget_composite_changed), table);
374 
375       /* The widget could die unexpectedly... */
376       g_object_weak_ref (G_OBJECT (table->priv->loaded_widget),
377                          (GWeakNotify) widget_finalized, table);
378 
379       if (table->priv->composite_check)
380 	{
381 	  GObject *object = glade_widget_get_object (table->priv->loaded_widget);
382 
383 	  if (GTK_IS_WIDGET (object) &&
384 	      glade_widget_get_parent (table->priv->loaded_widget) == NULL)
385 	    gtk_widget_show (table->priv->composite_check);
386 	  else
387 	    gtk_widget_hide (table->priv->composite_check);
388 	}
389 
390       if (table->priv->name_entry)
391 	{
392 	  if (glade_widget_has_name (widget))
393 	    gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), glade_widget_get_name (widget));
394 	  else
395 	    gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
396 	}
397 
398       if (table->priv->name_label)
399 	widget_composite_changed (widget, NULL, table);
400     }
401   else if (table->priv->name_entry)
402     gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
403 
404   UNBLOCK_NAME_ENTRY_CB (table);
405 
406   /* Sync up properties, even if widget is NULL */
407   for (list = table->priv->properties; list; list = list->next)
408     {
409       property = list->data;
410       glade_editor_property_load_by_widget (property, widget);
411     }
412 }
413 
414 static void
glade_editor_table_set_show_name(GladeEditable * editable,gboolean show_name)415 glade_editor_table_set_show_name (GladeEditable *editable, gboolean show_name)
416 {
417   GladeEditorTable *table = GLADE_EDITOR_TABLE (editable);
418 
419   if (table->priv->show_name != show_name)
420     {
421       table->priv->show_name = show_name;
422 
423       if (table->priv->name_label)
424 	{
425 	  gtk_widget_set_visible (table->priv->name_label, show_name);
426 	  gtk_widget_set_visible (table->priv->name_field, show_name);
427 	}
428     }
429 }
430 
431 static void
glade_editor_table_editable_init(GladeEditableIface * iface)432 glade_editor_table_editable_init (GladeEditableIface *iface)
433 {
434   iface->load = glade_editor_table_load;
435   iface->set_show_name = glade_editor_table_set_show_name;
436 }
437 
438 static void
glade_editor_table_attach(GladeEditorTable * table,GtkWidget * child,gint pos,gint row)439 glade_editor_table_attach (GladeEditorTable * table,
440                            GtkWidget * child, gint pos, gint row)
441 {
442   gtk_grid_attach (GTK_GRID (table), child, pos, row, 1, 1);
443 
444   if (pos)
445     gtk_widget_set_hexpand (child, TRUE);
446 }
447 
448 static gint
property_class_comp(gconstpointer a,gconstpointer b)449 property_class_comp (gconstpointer a, gconstpointer b)
450 {
451   GladePropertyClass *ca = (GladePropertyClass *)a, *cb = (GladePropertyClass *)b;
452   GParamSpec *pa, *pb;
453   const gchar *name_a, *name_b;
454 
455   pa = glade_property_class_get_pspec (ca);
456   pb = glade_property_class_get_pspec (cb);
457 
458   name_a = glade_property_class_id (ca);
459   name_b = glade_property_class_id (cb);
460 
461   /* Special case for the 'name' property, it *always* comes first. */
462   if (strcmp (name_a, "name") == 0)
463     return -1;
464   else if (strcmp (name_b, "name") == 0)
465     return 1;
466   /* Properties of the same class are sorted in the same level */
467   else if (pa->owner_type == pb->owner_type)
468     {
469       gdouble result = glade_property_class_weight (ca) - glade_property_class_weight (cb);
470       /* Avoid cast to int */
471       if (result < 0.0)
472         return -1;
473       else if (result > 0.0)
474         return 1;
475       else
476         return 0;
477     }
478   /* Group properties by thier class hierarchy */
479   else
480     {
481       if (g_type_is_a (pa->owner_type, pb->owner_type))
482         return (glade_property_class_common (ca) || glade_property_class_get_is_packing (ca)) ? 1 : -1;
483       else
484         return (glade_property_class_common (ca) || glade_property_class_get_is_packing (ca)) ? -1 : 1;
485     }
486 }
487 
488 static GList *
get_sorted_properties(GladeWidgetAdaptor * adaptor,GladeEditorPageType type)489 get_sorted_properties (GladeWidgetAdaptor *adaptor, GladeEditorPageType type)
490 {
491   const GList *l, *properties;
492   GList *list = NULL;
493 
494   properties =
495     (type == GLADE_PAGE_PACKING) ?
496     glade_widget_adaptor_get_packing_props (adaptor) :
497     glade_widget_adaptor_get_properties (adaptor);
498 
499   for (l = properties; l; l = g_list_next (l))
500     {
501       GladePropertyClass *klass = l->data;
502 
503       /* Collect properties in our domain, query dialogs are allowed editor
504        * invisible (or custom-layout) properties, allow adaptors to filter
505        * out properties from the GladeEditorTable using the "custom-layout" attribute.
506        */
507       if (GLADE_PROPERTY_CLASS_IS_TYPE (klass, type) &&
508 	  (type == GLADE_PAGE_QUERY ||
509 	   (!glade_property_class_custom_layout (klass) &&
510 	    glade_property_class_is_visible (klass))))
511         {
512           list = g_list_prepend (list, klass);
513         }
514 
515     }
516   return g_list_sort (list, property_class_comp);
517 }
518 
519 static GladeEditorProperty *
append_item(GladeEditorTable * table,GladePropertyClass * klass,gboolean from_query_dialog)520 append_item (GladeEditorTable   *table,
521              GladePropertyClass *klass,
522              gboolean            from_query_dialog)
523 {
524   GladeEditorProperty *property;
525   GtkWidget *label;
526 
527   if (!(property = glade_widget_adaptor_create_eprop
528         (glade_property_class_get_adaptor (klass), klass, from_query_dialog == FALSE)))
529     {
530       g_critical ("Unable to create editor for property '%s' of class '%s'",
531                   glade_property_class_id (klass),
532 		  glade_widget_adaptor_get_name (glade_property_class_get_adaptor (klass)));
533       return NULL;
534     }
535 
536   gtk_widget_show (GTK_WIDGET (property));
537   gtk_widget_show_all (glade_editor_property_get_item_label (property));
538 
539   label = glade_editor_property_get_item_label (property);
540   gtk_widget_set_hexpand (label, FALSE);
541 
542   glade_editor_table_attach (table, label, 0, table->priv->rows);
543   glade_editor_table_attach (table, GTK_WIDGET (property), 1, table->priv->rows);
544 
545   table->priv->rows++;
546 
547   return property;
548 }
549 
550 static void
append_items(GladeEditorTable * table,GladeWidgetAdaptor * adaptor,GladeEditorPageType type)551 append_items (GladeEditorTable   *table,
552               GladeWidgetAdaptor *adaptor,
553               GladeEditorPageType type)
554 {
555   GladeEditorProperty *property;
556   GladePropertyClass *property_class;
557   GList *list, *sorted_list;
558 
559   sorted_list = get_sorted_properties (adaptor, type);
560   for (list = sorted_list; list != NULL; list = list->next)
561     {
562       property_class = (GladePropertyClass *) list->data;
563 
564       property = append_item (table, property_class, type == GLADE_PAGE_QUERY);
565       table->priv->properties = g_list_prepend (table->priv->properties, property);
566     }
567   g_list_free (sorted_list);
568 
569   table->priv->properties = g_list_reverse (table->priv->properties);
570 }
571 
572 static void
append_name_field(GladeEditorTable * table)573 append_name_field (GladeEditorTable *table)
574 {
575   gchar *text = _("The object's unique identifier");
576 
577   /* translators: The unique identifier of an object in the project */
578   table->priv->name_label = gtk_label_new (_("ID:"));
579   gtk_widget_set_halign (table->priv->name_label, GTK_ALIGN_START);
580   gtk_widget_show (table->priv->name_label);
581   gtk_widget_set_no_show_all (table->priv->name_label, TRUE);
582 
583   table->priv->name_field = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
584   gtk_widget_set_no_show_all (table->priv->name_field, TRUE);
585   gtk_widget_show (table->priv->name_field);
586 
587   table->priv->composite_check = gtk_check_button_new_with_label (_("Composite"));
588   gtk_widget_set_hexpand (table->priv->composite_check, FALSE);
589   gtk_widget_set_tooltip_text (table->priv->composite_check, _("Whether this widget is a composite template"));
590   gtk_widget_set_no_show_all (table->priv->composite_check, TRUE);
591 
592   table->priv->name_entry = gtk_entry_new ();
593   gtk_widget_show (table->priv->name_entry);
594 
595   gtk_widget_set_tooltip_text (table->priv->name_label, text);
596   gtk_widget_set_tooltip_text (table->priv->name_entry, text);
597 
598   g_signal_connect (G_OBJECT (table->priv->name_entry), "activate",
599                     G_CALLBACK (widget_name_edited), table);
600   g_signal_connect (G_OBJECT (table->priv->name_entry), "changed",
601                     G_CALLBACK (widget_name_edited), table);
602   g_signal_connect (G_OBJECT (table->priv->composite_check), "toggled",
603                     G_CALLBACK (widget_composite_toggled), table);
604 
605   gtk_box_pack_start (GTK_BOX (table->priv->name_field), table->priv->name_entry, TRUE, TRUE, 0);
606   gtk_box_pack_start (GTK_BOX (table->priv->name_field), table->priv->composite_check, FALSE, FALSE, 0);
607 
608   glade_editor_table_attach (table, table->priv->name_label, 0, table->priv->rows);
609   glade_editor_table_attach (table, table->priv->name_field, 1, table->priv->rows);
610 
611   /* Set initial visiblity */
612   gtk_widget_set_visible (table->priv->name_label, table->priv->show_name);
613   gtk_widget_set_visible (table->priv->name_field, table->priv->show_name);
614 
615   table->priv->rows++;
616 }
617 
618 /**
619  * glade_editor_table_new:
620  * @adaptor: A #GladeWidgetAdaptor
621  * @type: The #GladeEditorPageType
622  *
623  * Creates a new #GladeEditorTable.
624  *
625  * Returns: a new #GladeEditorTable
626  *
627  */
628 GtkWidget *
glade_editor_table_new(GladeWidgetAdaptor * adaptor,GladeEditorPageType type)629 glade_editor_table_new (GladeWidgetAdaptor *adaptor, GladeEditorPageType type)
630 {
631   GladeEditorTable *table;
632 
633   g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
634 
635   table = g_object_new (GLADE_TYPE_EDITOR_TABLE, "page-type", type, NULL);
636   table->priv->adaptor = adaptor;
637 
638   if (table->priv->type == GLADE_PAGE_GENERAL)
639     append_name_field (table);
640 
641   append_items (table, table->priv->adaptor, table->priv->type);
642 
643   return (GtkWidget *)table;
644 }
645