aboutsummaryrefslogtreecommitdiffstats
path: root/e-util
diff options
context:
space:
mode:
Diffstat (limited to 'e-util')
-rw-r--r--e-util/e-account-utils.c5
-rw-r--r--e-util/e-account-utils.h5
-rw-r--r--e-util/e-binding.c2
-rw-r--r--e-util/e-config.c92
-rw-r--r--e-util/e-extensible.c93
-rw-r--r--e-util/e-extensible.h2
-rw-r--r--e-util/e-extension.c31
-rw-r--r--e-util/e-extension.h6
-rw-r--r--e-util/e-folder-map.c10
-rw-r--r--e-util/e-module.c6
-rw-r--r--e-util/e-module.h5
-rw-r--r--e-util/e-selection.c6
-rw-r--r--e-util/e-selection.h6
-rw-r--r--e-util/e-ui-manager.c9
-rw-r--r--e-util/e-ui-manager.h9
-rw-r--r--e-util/e-util.c9
-rw-r--r--e-util/e-util.h5
17 files changed, 248 insertions, 53 deletions
diff --git a/e-util/e-account-utils.c b/e-util/e-account-utils.c
index 4d169d956a..4395542f7c 100644
--- a/e-util/e-account-utils.c
+++ b/e-util/e-account-utils.c
@@ -15,6 +15,11 @@
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*/
+/**
+ * SECTION: e-account-utils
+ * @include: e-util/e-account-utils.h
+ **/
+
#include "e-account-utils.h"
#include <gconf/gconf-client.h>
diff --git a/e-util/e-account-utils.h b/e-util/e-account-utils.h
index ca184404ef..f2ae8fc5dc 100644
--- a/e-util/e-account-utils.h
+++ b/e-util/e-account-utils.h
@@ -15,11 +15,6 @@
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*/
-/**
- * SECTION: e-account-utils
- * @include: e-util/e-account-utils.h
- **/
-
#ifndef E_ACCOUNT_UTILS_H
#define E_ACCOUNT_UTILS_H
diff --git a/e-util/e-binding.c b/e-util/e-binding.c
index 86362a7eff..4b0f563a43 100644
--- a/e-util/e-binding.c
+++ b/e-util/e-binding.c
@@ -30,7 +30,7 @@ e_binding_warn (GObject *object,
const gchar *property_name)
{
g_warning (
- "%s instances have no `%s' property to bind to",
+ "%s instances have no '%s' property to bind to",
G_OBJECT_TYPE_NAME (object), property_name);
return NULL;
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));
diff --git a/e-util/e-extensible.c b/e-util/e-extensible.c
index 9960d31d9f..b718fc59bf 100644
--- a/e-util/e-extensible.c
+++ b/e-util/e-extensible.c
@@ -16,11 +16,54 @@
*
*/
+/**
+ * SECTION: e-extensible
+ * @short_description: an interface for extending objects
+ * @include: e-util/e-extensible.h
+ *
+ * #EExtension objects can be tacked on to any #GObject instance that
+ * implements the #EExtensible interface. A #GObject type can be made
+ * extensible in two steps:
+ *
+ * 1. Add the #EExtensible interface when registering the #GType.
+ * There are no methods to implement.
+ *
+ * <informalexample>
+ * <programlisting>
+ * #include <e-util/e-extensible.h>
+ *
+ * G_DEFINE_TYPE_WITH_CODE (
+ * ECustomWidget, e_custom_widget, GTK_TYPE_WIDGET,
+ * G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL))
+ * </programlisting>
+ * </informalexample>
+ *
+ * 2. Load extensions for the class at some point during #GObject
+ * initialization. Generally this should be done toward the end of
+ * the initialization code, so extensions get a fully initialized
+ * object to work with.
+ *
+ * <informalexample>
+ * <programlisting>
+ * static void
+ * e_custom_widget_init (ECustomWidget *widget)
+ * {
+ * Initialization code goes here...
+ *
+ * e_extensible_load_extensions (E_EXTENSIBLE (widget));
+ * }
+ * </programlisting>
+ * </informalexample>
+ **/
+
#include "e-extensible.h"
#include <e-util/e-util.h>
#include <e-util/e-extension.h>
+#define IS_AN_EXTENSION_TYPE(type) \
+ (g_type_is_a ((type), E_TYPE_EXTENSION))
+
static GQuark extensible_quark;
static GPtrArray *
@@ -89,6 +132,15 @@ e_extensible_get_type (void)
return type;
}
+/**
+ * e_extensible_load_extensions:
+ * @extensible: an #EExtensible
+ *
+ * Creates an instance of all instantiable subtypes of #EExtension which
+ * target the class of @extensible. The lifetimes of these newly created
+ * #EExtension objects are bound to @extensible such that they are finalized
+ * when @extensible is finalized.
+ **/
void
e_extensible_load_extensions (EExtensible *extensible)
{
@@ -110,3 +162,44 @@ e_extensible_load_extensions (EExtensible *extensible)
E_TYPE_EXTENSION, (ETypeFunc)
extensible_load_extension, extensible);
}
+
+/**
+ * e_extensible_list_extensions:
+ * @extensible: an #EExtensible
+ * @extension_type: the type of extensions to list
+ *
+ * Returns a list of #EExtension objects bound to @extensible whose
+ * types are ancestors of @extension_type. For a complete list of
+ * extension objects bound to @extensible, pass %E_TYPE_EXTENSION.
+ *
+ * The list itself should be freed with g_list_free(). The extension
+ * objects are owned by @extensible and should not be unreferenced.
+ *
+ * Returns: a list of extension objects derived from @extension_type
+ **/
+GList *
+e_extensible_list_extensions (EExtensible *extensible,
+ GType extension_type)
+{
+ GPtrArray *extensions;
+ GList *list = NULL;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_EXTENSIBLE (extensible), NULL);
+ g_return_val_if_fail (IS_AN_EXTENSION_TYPE (extension_type), NULL);
+
+ e_extensible_load_extensions (extensible);
+
+ extensions = extensible_get_extensions (extensible);
+ g_return_val_if_fail (extensions != NULL, NULL);
+
+ for (ii = 0; ii < extensions->len; ii++) {
+ GObject *object;
+
+ object = g_ptr_array_index (extensions, ii);
+ if (g_type_is_a (G_OBJECT_TYPE (object), extension_type))
+ list = g_list_prepend (list, object);
+ }
+
+ return g_list_reverse (list);
+}
diff --git a/e-util/e-extensible.h b/e-util/e-extensible.h
index a72ea71611..6dd6294212 100644
--- a/e-util/e-extensible.h
+++ b/e-util/e-extensible.h
@@ -51,6 +51,8 @@ struct _EExtensibleInterface {
GType e_extensible_get_type (void);
void e_extensible_load_extensions (EExtensible *extensible);
+GList * e_extensible_list_extensions (EExtensible *extensible,
+ GType extension_type);
G_END_DECLS
diff --git a/e-util/e-extension.c b/e-util/e-extension.c
index 05687b64ba..59eab840c9 100644
--- a/e-util/e-extension.c
+++ b/e-util/e-extension.c
@@ -16,6 +16,29 @@
*
*/
+/**
+ * SECTION: e-extension
+ * @short_description: abstract base class for extensions
+ * @include: e-util/e-extension.h
+ *
+ * #EExtension provides a way to extend the functionality of objects
+ * that implement the #EExtensible interface. #EExtension subclasses
+ * can target a particular extensible object type. New instances of
+ * an extensible object type get paired with a new instance of each
+ * #EExtension subclass that targets the extensible object type.
+ *
+ * The first steps of writing a new extension are as follows:
+ *
+ * 1. Subclass #EExtension.
+ *
+ * 2. In the class initialization function, specify the #GType being
+ * extended. The #GType must implement the #EExtensible interface.
+ *
+ * 3. Register the extension's own #GType. If the extension is to
+ * be loaded dynamically using #GTypeModule, the type should be
+ * registered in the library module's e_module_load() function.
+ **/
+
#include "e-extension.h"
#define E_EXTENSION_GET_PRIVATE(obj) \
@@ -151,6 +174,14 @@ e_extension_init (EExtension *extension)
extension->priv = E_EXTENSION_GET_PRIVATE (extension);
}
+/**
+ * e_extension_get_extensible:
+ * @extension: an #EExtension
+ *
+ * Returns the object that @extension extends.
+ *
+ * Returns: the object being extended
+ **/
EExtensible *
e_extension_get_extensible (EExtension *extension)
{
diff --git a/e-util/e-extension.h b/e-util/e-extension.h
index 905ef412f3..e9eee64a62 100644
--- a/e-util/e-extension.h
+++ b/e-util/e-extension.h
@@ -47,6 +47,12 @@ typedef struct _EExtension EExtension;
typedef struct _EExtensionClass EExtensionClass;
typedef struct _EExtensionPrivate EExtensionPrivate;
+/**
+ * EExtension:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EExtension {
GObject parent;
EExtensionPrivate *priv;
diff --git a/e-util/e-folder-map.c b/e-util/e-folder-map.c
index c77772f289..7d775bed8a 100644
--- a/e-util/e-folder-map.c
+++ b/e-util/e-folder-map.c
@@ -49,18 +49,18 @@ is_type_folder (const gchar *metadata, const gchar *search_type)
doc = e_xml_parse_file (metadata);
if (!doc) {
- g_warning ("Cannot parse `%s'", metadata);
+ g_warning ("Cannot parse '%s'", metadata);
return FALSE;
}
if (!(node = xmlDocGetRootElement (doc))) {
- g_warning ("`%s' corrupt: document contains no root node", metadata);
+ g_warning ("'%s' corrupt: document contains no root node", metadata);
xmlFreeDoc (doc);
return FALSE;
}
if (!node->name || strcmp ((gchar *)node->name, "efolder") != 0) {
- g_warning ("`%s' corrupt: root node is not 'efolder'", metadata);
+ g_warning ("'%s' corrupt: root node is not 'efolder'", metadata);
xmlFreeDoc (doc);
return FALSE;
}
@@ -122,7 +122,7 @@ e_folder_map_dir (const gchar *dirname, const gchar *type, GSList **dir_list)
}
if (!(dir = g_dir_open (path, 0, &error))) {
- g_warning ("cannot open `%s': %s", path, error->message);
+ g_warning ("cannot open '%s': %s", path, error->message);
g_error_free (error);
g_free (path);
return;
@@ -158,7 +158,7 @@ e_folder_map_local_folders (const gchar *local_dir, const gchar *type)
GError *error = NULL;
if (!(dir = g_dir_open (local_dir, 0, &error))) {
- g_warning ("cannot open `%s': %s", local_dir, error->message);
+ g_warning ("cannot open '%s': %s", local_dir, error->message);
g_error_free (error);
return NULL;
}
diff --git a/e-util/e-module.c b/e-util/e-module.c
index 3919841910..b61f5e7bdb 100644
--- a/e-util/e-module.c
+++ b/e-util/e-module.c
@@ -19,6 +19,12 @@
*
*/
+/**
+ * SECTION: e-module
+ * @short_description: a module loader
+ * @include: e-util/e-module.h
+ **/
+
#include "e-module.h"
#include <glib/gi18n.h>
diff --git a/e-util/e-module.h b/e-util/e-module.h
index 6f99fc0515..dc96bb34d9 100644
--- a/e-util/e-module.h
+++ b/e-util/e-module.h
@@ -19,11 +19,6 @@
*
*/
-/**
- * SECTION: e-module
- * @include: e-util/e-module.h
- **/
-
#ifndef E_MODULE_H
#define E_MODULE_H
diff --git a/e-util/e-selection.c b/e-util/e-selection.c
index 8be4c0b55a..3561dda636 100644
--- a/e-util/e-selection.c
+++ b/e-util/e-selection.c
@@ -19,6 +19,12 @@
*
*/
+/**
+ * SECTION: e-selection
+ * @short_description: selection and clipboard utilities
+ * @include: e-util/e-selection.h
+ **/
+
#include "e-selection.h"
#include <string.h>
diff --git a/e-util/e-selection.h b/e-util/e-selection.h
index f179180cd9..88ac772bae 100644
--- a/e-util/e-selection.h
+++ b/e-util/e-selection.h
@@ -19,12 +19,6 @@
*
*/
-/**
- * SECTION: e-selection
- * @short_description: selection and clipboard utilities
- * @include: e-util/e-selection.h
- **/
-
#ifndef E_SELECTION_H
#define E_SELECTION_H
diff --git a/e-util/e-ui-manager.c b/e-util/e-ui-manager.c
index 8c7455a054..f108cd37c5 100644
--- a/e-util/e-ui-manager.c
+++ b/e-util/e-ui-manager.c
@@ -16,6 +16,15 @@
*
*/
+/**
+ * SECTION: e-ui-manager
+ * @short_description: construct menus and toolbars from a UI definition
+ * @include: e-util/e-ui-manager.h
+ *
+ * This is a #GtkUIManager with support for Evolution's "express" mode,
+ * which influences the parsing of UI definitions.
+ **/
+
#include "e-ui-manager.h"
#include "e-util-private.h"
diff --git a/e-util/e-ui-manager.h b/e-util/e-ui-manager.h
index f0dc02c2cc..9b1f389d76 100644
--- a/e-util/e-ui-manager.h
+++ b/e-util/e-ui-manager.h
@@ -16,15 +16,6 @@
*
*/
-/**
- * SECTION: e-ui-manager
- * @short_description: construct menus and toolbars from a UI definition
- * @include: e-util/e-ui-manager.h
- *
- * This is a #GtkUIManager with support for Evolution's "express" mode,
- * which influences the parsing of UI definitions.
- **/
-
#ifndef E_UI_MANAGER_H
#define E_UI_MANAGER_H
diff --git a/e-util/e-util.c b/e-util/e-util.c
index cf5c0b0464..72ccd7a9e2 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -20,6 +20,11 @@
*
*/
+/**
+ * SECTION: e-util
+ * @include: e-util/e-util.h
+ **/
+
#include <config.h>
#include <stdlib.h>
@@ -237,7 +242,7 @@ e_lookup_action (GtkUIManager *ui_manager,
iter = g_list_next (iter);
}
- g_critical ("%s: action `%s' not found", G_STRFUNC, action_name);
+ g_critical ("%s: action '%s' not found", G_STRFUNC, action_name);
return NULL;
}
@@ -276,7 +281,7 @@ e_lookup_action_group (GtkUIManager *ui_manager,
iter = g_list_next (iter);
}
- g_critical ("%s: action group `%s' not found", G_STRFUNC, group_name);
+ g_critical ("%s: action group '%s' not found", G_STRFUNC, group_name);
return NULL;
}
diff --git a/e-util/e-util.h b/e-util/e-util.h
index dfbc6c0746..887cc20ce2 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -20,11 +20,6 @@
*
*/
-/**
- * SECTION: e-util
- * @include: e-util/e-util.h
- **/
-
#ifndef E_UTIL_H
#define E_UTIL_H