/* * Copyright (C) 2007 Juan Pablo Ugarte. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * 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 General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Authors: * Juan Pablo Ugarte */ /** * SECTION:glade-widget-action * @Title: GladeWidgetAction * @Short_Description: Context menu and toolbar actions. * * Use #GladeWidgetAction to create custom routines to operate * on widgets you add to glade, when running #GladeActionActivateFunc functions * you should make sure to use #GladeCommand. */ #include "glade-widget-action.h" #include "config.h" #include enum { PROP_0, PROP_CLASS, PROP_SENSITIVE, PROP_VISIBLE, N_PROPERTIES }; struct _GladeWidgetActionPrivate { GWActionClass *klass; /* The action class */ GList *actions; /* List of actions */ guint sensitive : 1; /* If this action is sensitive or not */ guint visible : 1; /* If this action is visible or not */ }; static GParamSpec *properties[N_PROPERTIES]; G_DEFINE_TYPE_WITH_PRIVATE (GladeWidgetAction, glade_widget_action, G_TYPE_OBJECT); static void glade_widget_action_init (GladeWidgetAction *object) { object->priv = glade_widget_action_get_instance_private (object); object->priv->sensitive = TRUE; object->priv->visible = TRUE; object->priv->actions = NULL; } static void glade_widget_action_finalize (GObject *object) { GladeWidgetAction *action = GLADE_WIDGET_ACTION (object); if (action->priv->actions) { g_list_foreach (action->priv->actions, (GFunc) g_object_unref, NULL); g_list_free (action->priv->actions); } G_OBJECT_CLASS (glade_widget_action_parent_class)->finalize (object); } static GObject * glade_widget_action_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { GladeWidgetAction *action; GObject *object; GList *l; object = G_OBJECT_CLASS (glade_widget_action_parent_class)->constructor (type, n_construct_properties, construct_properties); action = GLADE_WIDGET_ACTION (object); if (action->priv->klass == NULL) { g_warning ("GladeWidgetAction constructed without class property"); return object; } for (l = action->priv->klass->actions; l; l = g_list_next (l)) { GWActionClass *action_class = l->data; GObject *obj = g_object_new (GLADE_TYPE_WIDGET_ACTION, "class", action_class, NULL); action->priv->actions = g_list_prepend (action->priv->actions, GLADE_WIDGET_ACTION (obj)); } action->priv->actions = g_list_reverse (action->priv->actions); return object; } static void glade_widget_action_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GladeWidgetAction *action = GLADE_WIDGET_ACTION (object); g_return_if_fail (GLADE_IS_WIDGET_ACTION (object)); switch (prop_id) { case PROP_CLASS: action->priv->klass = g_value_get_pointer (value); break; case PROP_SENSITIVE: glade_widget_action_set_sensitive (action, g_value_get_boolean (value)); break; case PROP_VISIBLE: glade_widget_action_set_visible (action, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void glade_widget_action_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GladeWidgetAction *action = GLADE_WIDGET_ACTION (object); g_return_if_fail (GLADE_IS_WIDGET_ACTION (object)); switch (prop_id) { case PROP_CLASS: g_value_set_pointer (value, action->priv->klass); break; case PROP_SENSITIVE: g_value_set_boolean (value, action->priv->sensitive); break; case PROP_VISIBLE: g_value_set_boolean (value, action->priv->visible); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void glade_widget_action_class_init (GladeWidgetActionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = glade_widget_action_constructor; object_class->finalize = glade_widget_action_finalize; object_class->set_property = glade_widget_action_set_property; object_class->get_property = glade_widget_action_get_property; properties[PROP_CLASS] = g_param_spec_pointer ("class", _("class"), _("GladeWidgetActionClass structure pointer"), G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); properties[PROP_SENSITIVE] = g_param_spec_boolean ("sensitive", _("Sensitive"), _("Whether this action is sensitive"), TRUE, G_PARAM_READWRITE); properties[PROP_VISIBLE] = g_param_spec_boolean ("visible", _("Visible"), _("Whether this action is visible"), TRUE, G_PARAM_READWRITE); /* Install all properties */ g_object_class_install_properties (object_class, N_PROPERTIES, properties); } /** * glade_widget_action_set_sensitive: * @action: a #GladeWidgetAction * @sensitive: * * Set whether or not this action is sensitive. * */ void glade_widget_action_set_sensitive (GladeWidgetAction *action, gboolean sensitive) { g_return_if_fail (GLADE_IS_WIDGET_ACTION (action)); action->priv->sensitive = sensitive; g_object_notify_by_pspec (G_OBJECT (action), properties[PROP_SENSITIVE]); } gboolean glade_widget_action_get_sensitive (GladeWidgetAction *action) { g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE); return action->priv->sensitive; } void glade_widget_action_set_visible (GladeWidgetAction *action, gboolean visible) { g_return_if_fail (GLADE_IS_WIDGET_ACTION (action)); action->priv->visible = visible; g_object_notify_by_pspec (G_OBJECT (action), properties[PROP_VISIBLE]); } gboolean glade_widget_action_get_visible (GladeWidgetAction *action) { g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE); return action->priv->visible; } GList * glade_widget_action_get_children (GladeWidgetAction *action) { g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), NULL); return action->priv->actions; } GWActionClass * glade_widget_action_get_class (GladeWidgetAction *action) { g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), NULL); return action->priv->klass; } /*************************************************************** * GWActionClass * ***************************************************************/ static const gchar * gwa_action_path_get_id (const gchar *action_path) { const gchar *id; if ((id = g_strrstr (action_path, "/")) && id[1] != '\0') return &id[1]; else return action_path; } /** * glade_widget_action_class_new: * @path: the action path * * Returns: a newlly created #GWActionClass for @path. */ GWActionClass * glade_widget_action_class_new (const gchar *path) { GWActionClass *action; action = g_slice_new0 (GWActionClass); action->path = g_strdup (path); action->id = gwa_action_path_get_id (action->path); return action; } /** * glade_widget_action_class_clone: * @action: a GWActionClass * * Returns: a newlly allocated copy of @action. */ GWActionClass * glade_widget_action_class_clone (GWActionClass *action) { GWActionClass *copy; GList *l; g_return_val_if_fail (action != NULL, NULL); copy = glade_widget_action_class_new (action->path); copy->label = g_strdup (action->label); copy->stock = g_strdup (action->stock); copy->important = action->important; for (l = action->actions; l; l = g_list_next (l)) { GWActionClass *child = glade_widget_action_class_clone (l->data); copy->actions = g_list_prepend (copy->actions, child); } copy->actions = g_list_reverse (copy->actions); return copy; } /** * glade_widegt_action_class_free: * @action: a GWActionClass * * Frees a GWActionClass. */ void glade_widget_action_class_free (GWActionClass *action) { if (action->actions) g_list_foreach (action->actions, (GFunc) glade_widget_action_class_free, NULL); /* Dont free id since it points into path directly */ g_free (action->path); g_free (action->label); g_free (action->stock); g_slice_free (GWActionClass, action); } void glade_widget_action_class_set_label (GWActionClass *action, const gchar *label) { g_free (action->label); action->label = g_strdup (label); } void glade_widget_action_class_set_stock (GWActionClass *action, const gchar *stock) { g_free (action->stock); action->stock = g_strdup (stock); } void glade_widget_action_class_set_important (GWActionClass *action, gboolean important) { action->important = important; }