aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-03-05 05:31:17 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-03-14 09:53:17 +0800
commitc2685d9a6395fd6efb6b7cc2be28414c7fef2b5e (patch)
treebd2d411c98752931ef573e268f04af930aa04e6a
parentd7494c8f160b12e1199b06dcafdc8ff01b24b796 (diff)
downloadgsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar.gz
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar.bz2
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar.lz
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar.xz
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.tar.zst
gsoc2013-evolution-c2685d9a6395fd6efb6b7cc2be28414c7fef2b5e.zip
Forgot to commit the new source files...
-rw-r--r--e-util/e-ui-manager.c333
-rw-r--r--e-util/e-ui-manager.h83
2 files changed, 416 insertions, 0 deletions
diff --git a/e-util/e-ui-manager.c b/e-util/e-ui-manager.c
new file mode 100644
index 0000000000..c6a73042f0
--- /dev/null
+++ b/e-util/e-ui-manager.c
@@ -0,0 +1,333 @@
+/*
+ * e-ui-manager.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-ui-manager.h"
+
+#include <string.h>
+
+#define E_UI_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_UI_MANAGER, EUIManagerPrivate))
+
+/*
+ * --- NOTE TO SELF ---
+ *
+ * While creating this class I was tempted to add an "id" property which
+ * EPluginUI could extract from a given EUIManager instead of having the
+ * public EPluginUI functions take a separate "id" argument. Seemed like
+ * a nice cleanup until I remembered that an EUIManager instance can have
+ * multiple IDs ("aliases"), as in the case of EShellWindow's UI manager.
+ * So the UI Manager ID and the instance still need to be kept separate.
+ *
+ * Mentioning it here in case I forget why I didn't go through with it.
+ */
+
+struct _EUIManagerPrivate {
+ guint express_mode : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_EXPRESS_MODE
+};
+
+static gpointer parent_class;
+
+static void
+ui_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EXPRESS_MODE:
+ e_ui_manager_set_express_mode (
+ E_UI_MANAGER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+ui_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EXPRESS_MODE:
+ g_value_set_boolean (
+ value, e_ui_manager_get_express_mode (
+ E_UI_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static gchar *
+ui_manager_filter_ui (EUIManager *ui_manager,
+ const gchar *ui_definition)
+{
+ gchar **lines;
+ gchar *filtered;
+ gboolean express_mode;
+ gboolean in_conditional = FALSE;
+ gboolean include = TRUE;
+ gint ii;
+
+ express_mode = e_ui_manager_get_express_mode (ui_manager);
+
+ /*
+ * Very simple line based pre-processing based on comments:
+ * <!-- if [!]EXPRESS -->\n ... \n<!-- endif -->\n
+ */
+
+ lines = g_strsplit (ui_definition, "\n", -1);
+
+ for (ii = 0; lines[ii] != NULL; ii++) {
+ gchar *cp;
+
+ if ((cp = strstr (lines[ii], "<!-- if "))) {
+ gboolean not_express = lines[ii][8] == '!';
+ include = express_mode ^ not_express;
+ lines[ii][0] = '\0';
+ in_conditional = TRUE;
+ } else if ((cp = strstr (lines[ii], "<!-- endif"))) {
+ lines[ii][0] = '\0';
+ include = TRUE;
+ in_conditional = FALSE;
+ }
+ if (!include)
+ lines[ii][0] = '\0';
+ }
+
+ filtered = g_strjoinv ("\n", lines);
+
+ g_strfreev (lines);
+
+ return filtered;
+}
+
+static void
+ui_manager_class_init (EUIManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EUIManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = ui_manager_set_property;
+ object_class->get_property = ui_manager_get_property;
+
+ class->filter_ui = ui_manager_filter_ui;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EXPRESS_MODE,
+ g_param_spec_boolean (
+ "express-mode",
+ "Express Mode",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+ui_manager_init (EUIManager *ui_manager)
+{
+ ui_manager->priv = E_UI_MANAGER_GET_PRIVATE (ui_manager);
+}
+
+GType
+e_ui_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EUIManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ui_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EUIManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ui_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_UI_MANAGER, "EUIManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_ui_manager_new:
+ *
+ * Returns a new #EUIManager instance.
+ *
+ * Returns: a new #EUIManager instance
+ **/
+GtkUIManager *
+e_ui_manager_new (void)
+{
+ return g_object_new (E_TYPE_UI_MANAGER, NULL);
+}
+
+/**
+ * e_ui_manager_get_express_mode:
+ * @ui_manager: an #EUIManager
+ *
+ * Returns the "express mode" flag in @ui_manager.
+ *
+ * Returns: %TRUE if @ui_manager is set to express mode
+ **/
+gboolean
+e_ui_manager_get_express_mode (EUIManager *ui_manager)
+{
+ g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), FALSE);
+
+ return ui_manager->priv->express_mode;
+}
+
+/**
+ * e_ui_manager_set_express_mode:
+ * @ui_manager: an #EUIManager
+ * @express_mode: express mode flag
+ *
+ * Sets the "express mode" flag in @ui_manager, which influences how
+ * UI definitions are loaded.
+ **/
+void
+e_ui_manager_set_express_mode (EUIManager *ui_manager,
+ gboolean express_mode)
+{
+ g_return_if_fail (E_IS_UI_MANAGER (ui_manager));
+
+ ui_manager->priv->express_mode = express_mode;
+
+ g_object_notify (G_OBJECT (ui_manager), "express-mode");
+}
+
+/**
+ * e_ui_manager_add_ui_from_file:
+ * @ui_manager: an #EUIManager
+ * @basename: basename of the UI definition file
+ *
+ * Loads a UI definition into @ui_manager from Evolution's UI directory.
+ * If the EUIManager:express-mode property is %TRUE, a simplified version
+ * of the UI may be presented.
+ *
+ * Failure here is fatal, since the application can't function without
+ * its core UI definitions.
+ *
+ * Returns: The merge ID for the merged UI. The merge ID can be used to
+ * unmerge the UI with gtk_ui_manager_remove_ui().
+ **/
+guint
+e_ui_manager_add_ui_from_file (EUIManager *ui_manager,
+ const gchar *basename)
+{
+ EUIManagerClass *class;
+ gchar *filename;
+ gchar *contents;
+ guint merge_id = 0;
+ GError *error = NULL;
+
+ g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), 0);
+ g_return_val_if_fail (basename != NULL, 0);
+
+ class = E_UI_MANAGER_GET_CLASS (ui_manager);
+ g_return_val_if_fail (class->filter_ui != NULL, 0);
+
+ filename = g_build_filename (EVOLUTION_UIDIR, basename, NULL);
+
+ if (g_file_get_contents (filename, &contents, NULL, &error)) {
+ gchar *filtered;
+
+ /* We could call e_ui_manager_add_ui_from_string() here,
+ * but if an error occurs we'd like to include the file
+ * name in the error message. */
+
+ filtered = class->filter_ui (ui_manager, contents);
+
+ merge_id = gtk_ui_manager_add_ui_from_string (
+ GTK_UI_MANAGER (ui_manager), filtered, -1, &error);
+
+ g_free (filtered);
+ g_free (contents);
+ }
+
+ g_free (filename);
+
+ if (error != NULL) {
+ g_error ("%s: %s", basename, error->message);
+ g_assert_not_reached ();
+ }
+
+ return merge_id;
+}
+
+/**
+ * e_ui_manager_add_ui_from_string:
+ * @ui_manager: an #EUIManager
+ * @ui_definition: the UI XML in NULL terminated string form
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads the given UI definition into @ui_manager. If the
+ * EUIManager:express-mode property is %TRUE, a simplified version of
+ * the UI may be presented.
+ *
+ * Failure here is <i>not</i> fatal, since the function is primarily
+ * used to load UI definitions for plugins, which we can get by without.
+ *
+ * Returns: The merge ID for the merged UI. The merge ID can be used to
+ * unmerge the UI with gtk_ui_manager_remove_ui().
+ **/
+guint
+e_ui_manager_add_ui_from_string (EUIManager *ui_manager,
+ const gchar *ui_definition,
+ GError **error)
+{
+ EUIManagerClass *class;
+ gchar *filtered;
+ guint merge_id;
+
+ g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), 0);
+ g_return_val_if_fail (ui_definition != NULL, 0);
+
+ class = E_UI_MANAGER_GET_CLASS (ui_manager);
+ g_return_val_if_fail (class->filter_ui != NULL, 0);
+
+ filtered = class->filter_ui (ui_manager, ui_definition);
+
+ merge_id = gtk_ui_manager_add_ui_from_string (
+ GTK_UI_MANAGER (ui_manager), filtered, -1, error);
+
+ g_free (filtered);
+
+ return merge_id;
+}
diff --git a/e-util/e-ui-manager.h b/e-util/e-ui-manager.h
new file mode 100644
index 0000000000..f0dc02c2cc
--- /dev/null
+++ b/e-util/e-ui-manager.h
@@ -0,0 +1,83 @@
+/*
+ * e-ui-manager.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * 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
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_UI_MANAGER \
+ (e_ui_manager_get_type ())
+#define E_UI_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_UI_MANAGER, EUIManager))
+#define E_UI_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_UI_MANAGER, EUIManagerClass))
+#define E_IS_UI_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_UI_MANAGER))
+#define E_IS_UI_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_UI_MANAGER))
+#define E_UI_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_UI_MANAGER, EUIManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EUIManager EUIManager;
+typedef struct _EUIManagerClass EUIManagerClass;
+typedef struct _EUIManagerPrivate EUIManagerPrivate;
+
+struct _EUIManager {
+ GtkUIManager parent;
+ EUIManagerPrivate *priv;
+};
+
+struct _EUIManagerClass {
+ GtkUIManagerClass parent_class;
+
+ gchar * (*filter_ui) (EUIManager *ui_manager,
+ const gchar *ui_definition);
+};
+
+GType e_ui_manager_get_type (void);
+GtkUIManager * e_ui_manager_new (void);
+gboolean e_ui_manager_get_express_mode (EUIManager *ui_manager);
+void e_ui_manager_set_express_mode (EUIManager *ui_manager,
+ gboolean express_mode);
+guint e_ui_manager_add_ui_from_file (EUIManager *ui_manager,
+ const gchar *basename);
+guint e_ui_manager_add_ui_from_string (EUIManager *ui_manager,
+ const gchar *ui_definition,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_UI_MANAGER_H */