diff options
Diffstat (limited to 'widgets/misc/e-action-combo-box.c')
-rw-r--r-- | widgets/misc/e-action-combo-box.c | 578 |
1 files changed, 0 insertions, 578 deletions
diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c deleted file mode 100644 index 0747a6ed27..0000000000 --- a/widgets/misc/e-action-combo-box.c +++ /dev/null @@ -1,578 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-action-combo-box.c - * - * Copyright (C) 2008 Novell, Inc. - * - * 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.h> - -#define E_ACTION_COMBO_BOX_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxPrivate)) - -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 */ - gboolean group_has_icons : 1; -}; - -G_DEFINE_TYPE ( - EActionComboBox, - e_action_combo_box, - GTK_TYPE_COMBO_BOX) - -static void -action_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 -action_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 -action_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; - gint width; - - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - - /* Do any of the actions have an icon? */ - if (!combo_box->priv->group_has_icons) - return; - - /* A NULL action means the row is a separator. */ - if (action == NULL) - return; - - g_object_get ( - G_OBJECT (action), - "icon-name", &icon_name, - "sensitive", &sensitive, - "stock-id", &stock_id, - "visible", &visible, - NULL); - - /* Keep the pixbuf renderer a fixed size for proper alignment. */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL); - - /* We can't set both "icon-name" and "stock-id" because setting - * one unsets the other. So pick the one that has a non-NULL - * value. If both are non-NULL, "stock-id" wins. */ - - if (stock_id != NULL) - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "icon-name", NULL, - "stock-id", stock_id, - "stock-size", GTK_ICON_SIZE_MENU, - "visible", visible, - "width", width, - NULL); - else - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "icon-name", icon_name, - "stock-id", NULL, - "stock-size", GTK_ICON_SIZE_MENU, - "visible", visible, - "width", width, - NULL); - - g_free (icon_name); - g_free (stock_id); -} - -static void -action_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; - gint xpad; - - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - - /* A NULL action means the row is a separator. */ - if (action == NULL) - return; - - 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); - - xpad = combo_box->priv->group_has_icons ? 3 : 0; - - g_object_set ( - G_OBJECT (renderer), - "sensitive", sensitive, - "text", label, - "visible", visible, - "xpad", xpad, - NULL); - - g_free (label); -} - -static gboolean -action_combo_box_is_row_separator (GtkTreeModel *model, - GtkTreeIter *iter) -{ - GtkAction *action; - gboolean separator; - - /* NULL actions are rendered as separators. */ - gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); - separator = (action == NULL); - if (action != NULL) - g_object_unref (action); - - return separator; -} - -static void -action_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; - } - - /* We store values in the sort column as floats so that we can - * insert separators in between consecutive integer values and - * still maintain the proper ordering. */ - list_store = gtk_list_store_new ( - 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT); - - list = gtk_radio_action_get_group (combo_box->priv->action); - combo_box->priv->group_has_icons = FALSE; - - while (list != NULL) { - GtkTreeRowReference *reference; - GtkRadioAction *action = list->data; - GtkTreePath *path; - GtkTreeIter iter; - gchar *icon_name; - gchar *stock_id; - gint value; - - g_object_get ( - action, "icon-name", &icon_name, - "stock-id", &stock_id, NULL); - combo_box->priv->group_has_icons |= - (icon_name != NULL || stock_id != NULL); - g_free (icon_name); - g_free (stock_id); - - gtk_list_store_append (list_store, &iter); - g_object_get (action, "value", &value, NULL); - gtk_list_store_set ( - list_store, &iter, COLUMN_ACTION, - list->data, COLUMN_SORT, (gfloat) 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)); - - action_combo_box_action_changed_cb ( - combo_box->priv->action, - combo_box->priv->action, - combo_box); -} - -static void -action_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 -action_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 -action_combo_box_dispose (GObject *object) -{ - EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); - - 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 -action_combo_box_finalize (GObject *object) -{ - EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); - - 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 -action_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) action_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) action_combo_box_render_text, - combo_box, NULL); - - gtk_combo_box_set_row_separator_func ( - combo_box, (GtkTreeViewRowSeparatorFunc) - action_combo_box_is_row_separator, NULL, NULL); -} - -static void -action_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 (action, "value", &value, NULL); - gtk_radio_action_set_current_value (action, value); -} - -static void -e_action_combo_box_class_init (EActionComboBoxClass *class) -{ - GObjectClass *object_class; - GtkComboBoxClass *combo_box_class; - - g_type_class_add_private (class, sizeof (EActionComboBoxPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = action_combo_box_set_property; - object_class->get_property = action_combo_box_get_property; - object_class->dispose = action_combo_box_dispose; - object_class->finalize = action_combo_box_finalize; - object_class->constructed = action_combo_box_constructed; - - combo_box_class = GTK_COMBO_BOX_CLASS (class); - combo_box_class->changed = action_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 = E_ACTION_COMBO_BOX_GET_PRIVATE (combo_box); - - 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_ACTION_IS_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_ACTION_IS_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; - 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 (action_combo_box_action_changed_cb), - combo_box); - - if (combo_box->priv->action_group != NULL) { - g_object_ref (combo_box->priv->action_group); - combo_box->priv->group_sensitive_handler_id = - g_signal_connect ( - combo_box->priv->action_group, - "notify::sensitive", G_CALLBACK ( - action_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 ( - action_combo_box_action_group_notify_cb), - combo_box); - } - - g_object_notify (G_OBJECT (combo_box), "action"); -} - -gint -e_action_combo_box_get_current_value (EActionComboBox *combo_box) -{ - g_return_val_if_fail (E_ACTION_IS_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_ACTION_IS_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); -} - -void -e_action_combo_box_add_separator_before (EActionComboBox *combo_box, - gint action_value) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - - /* NULL actions are rendered as separators. */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, COLUMN_ACTION, - NULL, COLUMN_SORT, (gfloat) action_value - 0.5, -1); -} - -void -e_action_combo_box_add_separator_after (EActionComboBox *combo_box, - gint action_value) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); - - /* NULL actions are rendered as separators. */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, COLUMN_ACTION, - NULL, COLUMN_SORT, (gfloat) action_value + 0.5, -1); -} |