[evolution/webkit-composer: 6/11] Import GtkhtmlComboBox as EActionComboBox



commit 0e2f1dadb9f6055fc9f57db67bc4ca2592e97e28
Author: Dan VrÃtil <dvratil redhat com>
Date:   Wed Jul 25 15:40:21 2012 +0200

    Import GtkhtmlComboBox as EActionComboBox
    
    GtkhtmlComboBox => EActionComboBox

 widgets/editor/Makefile.am          |    2 +
 widgets/editor/e-action-combo-box.c |  463 +++++++++++++++++++++++++++++++++++
 widgets/editor/e-action-combo-box.h |   76 ++++++
 widgets/editor/e-editor-builder.ui  |    4 +-
 4 files changed, 543 insertions(+), 2 deletions(-)
---
diff --git a/widgets/editor/Makefile.am b/widgets/editor/Makefile.am
index 303a826..faea8f1 100644
--- a/widgets/editor/Makefile.am
+++ b/widgets/editor/Makefile.am
@@ -15,6 +15,8 @@ libeeditor_la_CPPFLAGS =					\
 	$(GNOME_PLATFORM_CFLAGS)
 
 libeeditor_la_SOURCES =						\
+	e-action-combo-box.c					\
+	e-action-combo-box.h					\
 	e-color-chooser-widget.c				\
 	e-color-chooser-widget.h				\
 	e-color-combo.c						\
diff --git a/widgets/editor/e-action-combo-box.c b/widgets/editor/e-action-combo-box.c
new file mode 100644
index 0000000..bb6f0f9
--- /dev/null
+++ b/widgets/editor/e-action-combo-box.c
@@ -0,0 +1,463 @@
+/* e-action-combo-box.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-action-combo-box.h"
+
+#include <glib/gi18n-lib.h>
+
+G_DEFINE_TYPE (
+	EActionComboBox,
+	e_action_combo_box,
+	GTK_TYPE_COMBO_BOX);
+
+enum {
+	COLUMN_ACTION,
+	COLUMN_SORT
+};
+
+enum {
+	PROP_0,
+	PROP_ACTION
+};
+
+struct _EActionComboBoxPrivate {
+	GtkRadioAction *action;
+	GtkActionGroup *action_group;
+	GHashTable *index;
+	guint changed_handler_id;		/* action::changed */
+	guint group_sensitive_handler_id;	/* action-group::sensitive */
+	guint group_visible_handler_id;		/* action-group::visible */
+};
+
+static void
+combo_box_action_changed_cb (GtkRadioAction *action,
+                             GtkRadioAction *current,
+                             EActionComboBox *combo_box)
+{
+	GtkTreeRowReference *reference;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	gboolean valid;
+
+	reference = g_hash_table_lookup (
+		combo_box->priv->index, GINT_TO_POINTER (
+		gtk_radio_action_get_current_value (current)));
+	g_return_if_fail (reference != NULL);
+
+	model = gtk_tree_row_reference_get_model (reference);
+	path = gtk_tree_row_reference_get_path (reference);
+	valid = gtk_tree_model_get_iter (model, &iter, path);
+	gtk_tree_path_free (path);
+	g_return_if_fail (valid);
+
+	gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
+}
+
+static void
+combo_box_action_group_notify_cb (GtkActionGroup *action_group,
+                                  GParamSpec *pspec,
+                                  EActionComboBox *combo_box)
+{
+	g_object_set (
+		combo_box, "sensitive",
+		gtk_action_group_get_sensitive (action_group), "visible",
+		gtk_action_group_get_visible (action_group), NULL);
+}
+
+static void
+combo_box_render_pixbuf (GtkCellLayout *layout,
+                         GtkCellRenderer *renderer,
+                         GtkTreeModel *model,
+                         GtkTreeIter *iter,
+                         EActionComboBox *combo_box)
+{
+	GtkRadioAction *action;
+	gchar *icon_name;
+	gchar *stock_id;
+	gboolean sensitive;
+	gboolean visible;
+
+	gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+
+	g_object_get (
+		G_OBJECT (action),
+		"icon-name", &icon_name,
+		"sensitive", &sensitive,
+		"stock-id", &stock_id,
+		"visible", &visible,
+		NULL);
+
+	g_object_set (
+		G_OBJECT (renderer),
+		"icon-name", icon_name,
+		"sensitive", sensitive,
+		"stock-id", stock_id,
+		"stock-size", GTK_ICON_SIZE_MENU,
+		"visible", visible,
+		NULL);
+
+	g_free (icon_name);
+	g_free (stock_id);
+}
+
+static void
+combo_box_render_text (GtkCellLayout *layout,
+                       GtkCellRenderer *renderer,
+                       GtkTreeModel *model,
+                       GtkTreeIter *iter,
+                       EActionComboBox *combo_box)
+{
+	GtkRadioAction *action;
+	gchar **strv;
+	gchar *label;
+	gboolean sensitive;
+	gboolean visible;
+
+	gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+
+	g_object_get (
+		G_OBJECT (action),
+		"label", &label,
+		"sensitive", &sensitive,
+		"visible", &visible,
+		NULL);
+
+	/* Strip out underscores. */
+	strv = g_strsplit (label, "_", -1);
+	g_free (label);
+	label = g_strjoinv (NULL, strv);
+	g_strfreev (strv);
+
+	g_object_set (
+		G_OBJECT (renderer),
+		"sensitive", sensitive,
+		"text", label,
+		"visible", visible,
+		NULL);
+
+	g_free (label);
+}
+
+static void
+combo_box_update_model (EActionComboBox *combo_box)
+{
+	GtkListStore *list_store;
+	GSList *list;
+
+	g_hash_table_remove_all (combo_box->priv->index);
+
+	if (combo_box->priv->action == NULL) {
+		gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL);
+		return;
+	}
+
+	list_store = gtk_list_store_new (
+		2, GTK_TYPE_RADIO_ACTION, G_TYPE_INT);
+
+	list = gtk_radio_action_get_group (combo_box->priv->action);
+
+	while (list != NULL) {
+		GtkTreeRowReference *reference;
+		GtkRadioAction *action = list->data;
+		GtkTreePath *path;
+		GtkTreeIter iter;
+		gint value;
+
+		gtk_list_store_append (list_store, &iter);
+		g_object_get (G_OBJECT (action), "value", &value, NULL);
+		gtk_list_store_set (
+			list_store, &iter, COLUMN_ACTION,
+			list->data, COLUMN_SORT, value, -1);
+
+		path = gtk_tree_model_get_path (
+			GTK_TREE_MODEL (list_store), &iter);
+		reference = gtk_tree_row_reference_new (
+			GTK_TREE_MODEL (list_store), path);
+		g_hash_table_insert (
+			combo_box->priv->index,
+			GINT_TO_POINTER (value), reference);
+		gtk_tree_path_free (path);
+
+		list = g_slist_next (list);
+	}
+
+	gtk_tree_sortable_set_sort_column_id (
+		GTK_TREE_SORTABLE (list_store),
+		COLUMN_SORT, GTK_SORT_ASCENDING);
+	gtk_combo_box_set_model (
+		GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (list_store));
+
+	combo_box_action_changed_cb (
+		combo_box->priv->action,
+		combo_box->priv->action,
+		combo_box);
+}
+
+static void
+combo_box_set_property (GObject *object,
+                        guint property_id,
+                        const GValue *value,
+                        GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACTION:
+			e_action_combo_box_set_action (
+				E_ACTION_COMBO_BOX (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+combo_box_get_property (GObject *object,
+                        guint property_id,
+                        GValue *value,
+                        GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACTION:
+			g_value_set_object (
+				value, e_action_combo_box_get_action (
+				E_ACTION_COMBO_BOX (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+combo_box_dispose (GObject *object)
+{
+	EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX (object)->priv;
+
+	if (priv->action != NULL) {
+		g_object_unref (priv->action);
+		priv->action = NULL;
+	}
+
+	if (priv->action_group != NULL) {
+		g_object_unref (priv->action_group);
+		priv->action_group = NULL;
+	}
+
+	g_hash_table_remove_all (priv->index);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_action_combo_box_parent_class)->dispose (object);
+}
+
+static void
+combo_box_finalize (GObject *object)
+{
+	EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX (object)->priv;
+
+	g_hash_table_destroy (priv->index);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_action_combo_box_parent_class)->finalize (object);
+}
+
+static void
+combo_box_constructed (GObject *object)
+{
+	GtkComboBox *combo_box;
+	GtkCellRenderer *renderer;
+
+	combo_box = GTK_COMBO_BOX (object);
+
+	/* This needs to happen after constructor properties are set
+	 * so that GtkCellLayout.get_area() returns something valid. */
+
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	gtk_cell_layout_pack_start (
+		GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
+	gtk_cell_layout_set_cell_data_func (
+		GTK_CELL_LAYOUT (combo_box), renderer,
+		(GtkCellLayoutDataFunc) combo_box_render_pixbuf,
+		combo_box, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_cell_layout_pack_start (
+		GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
+	gtk_cell_layout_set_cell_data_func (
+		GTK_CELL_LAYOUT (combo_box), renderer,
+		(GtkCellLayoutDataFunc) combo_box_render_text,
+		combo_box, NULL);
+}
+
+static void
+combo_box_changed (GtkComboBox *combo_box)
+{
+	GtkRadioAction *action;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gint value;
+
+	/* This method is virtual, so no need to chain up. */
+
+	if (!gtk_combo_box_get_active_iter (combo_box, &iter))
+		return;
+
+	model = gtk_combo_box_get_model (combo_box);
+	gtk_tree_model_get (model, &iter, COLUMN_ACTION, &action, -1);
+	g_object_get (G_OBJECT (action), "value", &value, NULL);
+	gtk_radio_action_set_current_value (action, value);
+}
+
+static void
+e_action_combo_box_class_init (EActionComboBoxClass *klass)
+{
+	GObjectClass *object_class;
+	GtkComboBoxClass *combo_box_class;
+
+	e_action_combo_box_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (EActionComboBoxPrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->set_property = combo_box_set_property;
+	object_class->get_property = combo_box_get_property;
+	object_class->dispose = combo_box_dispose;
+	object_class->finalize = combo_box_finalize;
+	object_class->constructed = combo_box_constructed;
+
+	combo_box_class = GTK_COMBO_BOX_CLASS (klass);
+	combo_box_class->changed = combo_box_changed;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ACTION,
+		g_param_spec_object (
+			"action",
+			"Action",
+			"A GtkRadioAction",
+			GTK_TYPE_RADIO_ACTION,
+			G_PARAM_READWRITE));
+}
+
+static void
+e_action_combo_box_init (EActionComboBox *combo_box)
+{
+	combo_box->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+		combo_box, E_TYPE_ACTION_COMBO_BOX, EActionComboBoxPrivate);
+
+	combo_box->priv->index = g_hash_table_new_full (
+		g_direct_hash, g_direct_equal,
+		(GDestroyNotify) NULL,
+		(GDestroyNotify) gtk_tree_row_reference_free);
+}
+
+GtkWidget *
+e_action_combo_box_new (void)
+{
+	return e_action_combo_box_new_with_action (NULL);
+}
+
+GtkWidget *
+e_action_combo_box_new_with_action (GtkRadioAction *action)
+{
+	return g_object_new (E_TYPE_ACTION_COMBO_BOX, "action", action, NULL);
+}
+
+GtkRadioAction *
+e_action_combo_box_get_action (EActionComboBox *combo_box)
+{
+	g_return_val_if_fail (E_IS_ACTION_COMBO_BOX (combo_box), NULL);
+
+	return combo_box->priv->action;
+}
+
+void
+e_action_combo_box_set_action (EActionComboBox *combo_box,
+			       GtkRadioAction *action)
+{
+	g_return_if_fail (E_IS_ACTION_COMBO_BOX (combo_box));
+
+	if (action != NULL)
+		g_return_if_fail (GTK_IS_RADIO_ACTION (action));
+
+	if (combo_box->priv->action != NULL) {
+		g_signal_handler_disconnect (
+			combo_box->priv->action,
+			combo_box->priv->changed_handler_id);
+		g_object_unref (combo_box->priv->action);
+	}
+
+	if (combo_box->priv->action_group != NULL) {
+		g_signal_handler_disconnect (
+			combo_box->priv->action_group,
+			combo_box->priv->group_sensitive_handler_id);
+		g_signal_handler_disconnect (
+			combo_box->priv->action_group,
+			combo_box->priv->group_visible_handler_id);
+		g_object_unref (combo_box->priv->action_group);
+		combo_box->priv->action_group = NULL;
+	}
+
+	if (action != NULL)
+		g_object_get (
+			g_object_ref (action), "action-group",
+			&combo_box->priv->action_group, NULL);
+	combo_box->priv->action = action;
+	combo_box_update_model (combo_box);
+
+	if (combo_box->priv->action != NULL)
+		combo_box->priv->changed_handler_id = g_signal_connect (
+			combo_box->priv->action, "changed",
+			G_CALLBACK (combo_box_action_changed_cb), combo_box);
+
+	if (combo_box->priv->action_group != NULL) {
+		combo_box->priv->group_sensitive_handler_id =
+			g_signal_connect (
+				combo_box->priv->action_group,
+				"notify::sensitive",
+				G_CALLBACK (combo_box_action_group_notify_cb),
+				combo_box);
+		combo_box->priv->group_visible_handler_id =
+			g_signal_connect (
+				combo_box->priv->action_group,
+				"notify::visible",
+				G_CALLBACK (combo_box_action_group_notify_cb),
+				combo_box);
+	}
+}
+
+gint
+e_action_combo_box_get_current_value (EActionComboBox *combo_box)
+{
+	g_return_val_if_fail (E_IS_ACTION_COMBO_BOX (combo_box), 0);
+	g_return_val_if_fail (combo_box->priv->action != NULL, 0);
+
+	return gtk_radio_action_get_current_value (combo_box->priv->action);
+}
+
+void
+e_action_combo_box_set_current_value (EActionComboBox *combo_box,
+				      gint current_value)
+{
+	g_return_if_fail (E_IS_ACTION_COMBO_BOX (combo_box));
+	g_return_if_fail (combo_box->priv->action != NULL);
+
+	gtk_radio_action_set_current_value (
+		combo_box->priv->action, current_value);
+}
diff --git a/widgets/editor/e-action-combo-box.h b/widgets/editor/e-action-combo-box.h
new file mode 100644
index 0000000..9a172d9
--- /dev/null
+++ b/widgets/editor/e-action-combo-box.h
@@ -0,0 +1,76 @@
+/* e-action-combo-box.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef E_ACTION_COMBO_BOX_H
+#define E_ACTION_COMBO_BOX_H
+
+/* This is a GtkComboBox that is driven by a group of GtkRadioActions.
+ * Just plug in a GtkRadioAction and the widget will handle the rest. */
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACTION_COMBO_BOX \
+	(e_action_combo_box_get_type ())
+#define E_ACTION_COMBO_BOX(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBox))
+#define E_ACTION_COMBO_BOX_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass))
+#define E_IS_ACTION_COMBO_BOX(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_ACTION_COMBO_BOX))
+#define E_IS_ACTION_COMBO_BOX_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_ACTION_COMBO_BOX))
+#define E_ACTION_COMBO_BOX_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EActionComboBox EActionComboBox;
+typedef struct _EActionComboBoxClass EActionComboBoxClass;
+typedef struct _EActionComboBoxPrivate EActionComboBoxPrivate;
+
+struct _EActionComboBox {
+	GtkComboBox parent;
+	EActionComboBoxPrivate *priv;
+};
+
+struct _EActionComboBoxClass {
+	GtkComboBoxClass parent_class;
+};
+
+GType		e_action_combo_box_get_type	(void);
+GtkWidget *	e_action_combo_box_new		(void);
+GtkWidget *	e_action_combo_box_new_with_action
+						(GtkRadioAction *action);
+GtkRadioAction *
+		e_action_combo_box_get_action	(EActionComboBox *combo_box);
+void		e_action_combo_box_set_action	(EActionComboBox *combo_box,
+						 GtkRadioAction *action);
+gint		e_action_combo_box_get_current_value
+						(EActionComboBox *combo_box);
+void		e_action_combo_box_set_current_value
+						(EActionComboBox *combo_box,
+						 gint current_value);
+
+G_END_DECLS
+
+#endif /* E_ACTION_COMBO_BOX_H */
diff --git a/widgets/editor/e-editor-builder.ui b/widgets/editor/e-editor-builder.ui
index f8eb82b..0e23212 100644
--- a/widgets/editor/e-editor-builder.ui
+++ b/widgets/editor/e-editor-builder.ui
@@ -521,7 +521,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkhtmlComboBox" id="text-properties-size-combo-box">
+                  <object class="EActionComboBox" id="text-properties-size-combo-box">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                   </object>
@@ -628,7 +628,7 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkhtmlComboBox" id="paragraph-properties-style-combo-box">
+                      <object class="EActionComboBox" id="paragraph-properties-style-combo-box">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                       </object>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]