diff options
Diffstat (limited to 'e-util/e-config.c')
-rw-r--r-- | e-util/e-config.c | 92 |
1 files changed, 77 insertions, 15 deletions
diff --git a/e-util/e-config.c b/e-util/e-config.c index 613971fba5..e8eedffef8 100644 --- a/e-util/e-config.c +++ b/e-util/e-config.c @@ -41,6 +41,8 @@ #define d(x) +typedef GtkWidget * (*EConfigItemSectionFactoryFunc)(EConfig *ec, EConfigItem *, GtkWidget *parent, GtkWidget *old, gpointer data, GtkWidget **real_frame); + struct _EConfigFactory { gchar *id; EConfigFactoryFunc func; @@ -62,6 +64,7 @@ struct _widget_node { EConfigItem *item; GtkWidget *widget; /* widget created by the factory, if any */ GtkWidget *frame; /* if created by us */ + GtkWidget *real_frame; /* used for sections and section tables, this is the real GtkFrame (whereas "frame" above is the internal vbox/table) */ guint empty:1; /* set if empty (i.e. hidden) */ }; @@ -87,6 +90,8 @@ struct _EConfigPrivate { static gpointer parent_class; +static GtkWidget *ech_config_section_factory (EConfig *config, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data, GtkWidget **real_frame); + static void config_finalize (GObject *object) { @@ -94,7 +99,7 @@ config_finalize (GObject *object) EConfigPrivate *p = emp->priv; GList *link; - d(printf("finalising EConfig %p\n", o)); + d(printf("finalising EConfig %p\n", object)); g_free(emp->id); @@ -519,6 +524,7 @@ ec_rebuild (EConfig *emp) struct _widget_node *sectionnode = NULL, *pagenode = NULL; GtkWidget *book = NULL, *page = NULL, *section = NULL, *root = NULL, *assistant = NULL; gint pageno = 0, sectionno = 0, itemno = 0; + gint n_visible_widgets = 0; struct _widget_node *last_active_page = NULL; gboolean is_assistant; GList *link; @@ -550,7 +556,7 @@ ec_rebuild (EConfig *emp) if (item->label != NULL) translated_label = gettext (item->label); - /* If the last section doesn't contain anything, hide it */ + /* If the last section doesn't contain any visible widgets, hide it */ if (sectionnode != NULL && sectionnode->frame != NULL && (item->type == E_CONFIG_PAGE_START @@ -558,11 +564,22 @@ ec_rebuild (EConfig *emp) || item->type == E_CONFIG_PAGE || item->type == E_CONFIG_SECTION || item->type == E_CONFIG_SECTION_TABLE)) { - if ((sectionnode->empty = itemno == 0)) { - gtk_widget_hide(sectionnode->frame); + if ((sectionnode->empty = (itemno == 0 || n_visible_widgets == 0))) { + if (sectionnode->real_frame) + gtk_widget_hide(sectionnode->real_frame); + + if (sectionnode->frame) + gtk_widget_hide(sectionnode->frame); + sectionno--; - } else - gtk_widget_show(sectionnode->frame); + } else { + if (sectionnode->real_frame) + gtk_widget_show(sectionnode->real_frame); + + if (sectionnode->frame) + gtk_widget_show(sectionnode->frame); + } + d(printf("%s section '%s' [sections=%d]\n", sectionnode->empty?"hiding":"showing", sectionnode->item->path, sectionno)); } @@ -791,12 +808,35 @@ ec_rebuild (EConfig *emp) } itemno = 0; + n_visible_widgets = 0; + + d(printf("Building section %s - '%s' - %s factory\n", item->path, item->label, item->factory ? "with" : "without")); + if (item->factory) { - section = item->factory(emp, item, page, wn->widget, wn->context->data); + /* For sections, we pass an extra argument to the usual EConfigItemFactoryFunc. + * If this is an automatically-generated section, that extra argument (real_frame from + * EConfigItemSectionFactoryFunc) will contain the actual GtkFrame upon returning. + */ + EConfigItemSectionFactoryFunc factory = (EConfigItemSectionFactoryFunc) item->factory; + + section = factory(emp, item, page, wn->widget, wn->context->data, &wn->real_frame); wn->frame = section; if (section) itemno = 1; + if (factory != ech_config_section_factory) { + /* This means there is a section that came from a user-specified factory, + * so we don't know what is inside the section. In that case, we increment + * n_visible_widgets so that the section will not get hidden later (we don't know + * if the section is empty or not, so we cannot decide to hide it). + * + * For automatically-generated sections, we use a special ech_config_section_factory() - + * see emph_construct_item(). + */ + n_visible_widgets++; + d(printf (" n_visible_widgets++ because there is a section factory -> frame=%p\n", section)); + } + if (section && ((item->type == E_CONFIG_SECTION && !GTK_IS_BOX(section)) || (item->type == E_CONFIG_SECTION_TABLE && !GTK_IS_TABLE(section)))) @@ -878,6 +918,11 @@ ec_rebuild (EConfig *emp) d(printf("item %d:%s widget %p\n", itemno, item->path, w)); + d(printf (" item %s: (%s - %s)\n", + item->path, + g_type_name_from_instance ((GTypeInstance *) w), + gtk_widget_get_visible (w) ? "visible" : "invisible")); + if (wn->widget && wn->widget != w) { d(printf("destroy old widget for item '%s'\n", item->path)); gtk_widget_destroy(wn->widget); @@ -887,18 +932,32 @@ ec_rebuild (EConfig *emp) if (w) { g_signal_connect(w, "destroy", G_CALLBACK(gtk_widget_destroyed), &wn->widget); itemno++; + + if (gtk_widget_get_visible (w)) + n_visible_widgets++; } break; } } - /* If the last section doesn't contain anything, hide it */ + /* If the last section doesn't contain any visible widgets, hide it */ if (sectionnode != NULL && sectionnode->frame != NULL) { - if ((sectionnode->empty = itemno == 0)) { - gtk_widget_hide(sectionnode->frame); + d(printf ("Section %s - %d visible widgets (frame=%p)\n", sectionnode->item->path, n_visible_widgets, sectionnode->frame)); + if ((sectionnode->empty = (itemno == 0 || n_visible_widgets == 0))) { + if (sectionnode->real_frame) + gtk_widget_hide(sectionnode->real_frame); + + if (sectionnode->frame) + gtk_widget_hide(sectionnode->frame); + sectionno--; - } else - gtk_widget_show(sectionnode->frame); + } else { + if (sectionnode->real_frame) + gtk_widget_show(sectionnode->real_frame); + + if (sectionnode->frame) + gtk_widget_show(sectionnode->frame); + } d(printf("%s section '%s' [sections=%d]\n", sectionnode->empty?"hiding":"showing", sectionnode->item->path, sectionno)); } @@ -1585,7 +1644,8 @@ ech_config_section_factory (EConfig *config, EConfigItem *item, GtkWidget *parent, GtkWidget *old, - gpointer data) + gpointer data, + GtkWidget **real_frame) { struct _EConfigHookGroup *group = data; GtkWidget *label = NULL; @@ -1612,6 +1672,8 @@ ech_config_section_factory (EConfig *config, gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_NONE); gtk_box_pack_start (GTK_BOX (parent), widget, FALSE, FALSE, 0); + *real_frame = widget; + /* This is why we have a custom factory for sections. * When the plugin is disabled the frame is invisible. */ plugin = group->hook->hook.plugin; @@ -1667,9 +1729,9 @@ emph_construct_item(EPluginHook *eph, EConfigHookGroup *menu, xmlNodePtr root, E if (item->user_data) item->factory = ech_config_widget_factory; else if (item->type == E_CONFIG_SECTION) - item->factory = ech_config_section_factory; + item->factory = (EConfigItemFactoryFunc) ech_config_section_factory; else if (item->type == E_CONFIG_SECTION_TABLE) - item->factory = ech_config_section_factory; + item->factory = (EConfigItemFactoryFunc) ech_config_section_factory; d(printf(" path=%s label=%s factory=%s\n", item->path, item->label, (gchar *)item->user_data)); |