517 lines
16 KiB
C
517 lines
16 KiB
C
/*
|
|
* mooactionbase.c
|
|
*
|
|
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
|
*
|
|
* 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.
|
|
*
|
|
* See COPYING file that comes with this distribution.
|
|
*/
|
|
|
|
#include "mooutils/mooactionbase-private.h"
|
|
#include "mooutils/mooaction-private.h"
|
|
#include "mooutils/mooactiongroup.h"
|
|
#include <gtk/gtkaction.h>
|
|
#include <gtk/gtkstock.h>
|
|
#include <string.h>
|
|
|
|
enum {
|
|
MOO_ACTION_BASE_PROPS(MOO_ACTION_BASE)
|
|
};
|
|
|
|
|
|
static void
|
|
moo_action_base_class_init (gpointer g_iface)
|
|
{
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_string ("display-name", "display-name", "display-name",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_string ("accel", "accel", "accel",
|
|
NULL,
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_boolean ("no-accel", "no-accel", "no-accel",
|
|
FALSE,
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_boolean ("force-accel-label", "force-accel-label", "force-accel-label",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_boolean ("dead", "dead", "dead",
|
|
FALSE,
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_boolean ("active", "active", "active",
|
|
TRUE,
|
|
G_PARAM_WRITABLE));
|
|
g_object_interface_install_property (g_iface,
|
|
g_param_spec_boolean ("has-submenu", "has-submenu", "has-submenu",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_base_init_class (GObjectClass *klass)
|
|
{
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_DISPLAY_NAME,
|
|
g_param_spec_string ("display-name", "display-name", "display-name",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_ACCEL,
|
|
g_param_spec_string ("accel", "accel", "accel",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_NO_ACCEL,
|
|
g_param_spec_boolean ("no-accel", "no-accel", "no-accel",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_FORCE_ACCEL_LABEL,
|
|
g_param_spec_boolean ("force-accel-label", "force-accel-label", "force-accel-label",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_DEAD,
|
|
g_param_spec_boolean ("dead", "dead", "dead",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_ACTIVE,
|
|
g_param_spec_boolean ("active", "active", "active",
|
|
TRUE,
|
|
G_PARAM_WRITABLE));
|
|
g_object_class_install_property (klass, MOO_ACTION_BASE_PROP_HAS_SUBMENU,
|
|
g_param_spec_boolean ("has-submenu", "has-submenu", "has-submenu",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_override_property (klass,
|
|
MOO_ACTION_BASE_PROP_LABEL,
|
|
"label");
|
|
g_object_class_override_property (klass,
|
|
MOO_ACTION_BASE_PROP_TOOLTIP,
|
|
"tooltip");
|
|
}
|
|
|
|
|
|
GType
|
|
moo_action_base_get_type (void)
|
|
{
|
|
static GType type;
|
|
|
|
if (!type)
|
|
{
|
|
static const GTypeInfo info = {
|
|
sizeof (MooActionBaseClass), /* class_size */
|
|
NULL, /* base_init */
|
|
NULL, /* base_finalize */
|
|
(GClassInitFunc) moo_action_base_class_init, /* class_init */
|
|
NULL, /* class_finalize */
|
|
NULL, /* class_data */
|
|
0,
|
|
0, /* n_preallocs */
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
type = g_type_register_static (G_TYPE_INTERFACE,
|
|
"MooActionBase",
|
|
&info, 0);
|
|
g_type_interface_add_prerequisite (type, GTK_TYPE_ACTION);
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
|
|
static char *
|
|
strip_underscore (const char *label)
|
|
{
|
|
char *stripped, *underscore;
|
|
|
|
g_return_val_if_fail (label != NULL, NULL);
|
|
|
|
stripped = g_strdup (label);
|
|
underscore = strchr (stripped, '_');
|
|
|
|
if (underscore)
|
|
memmove (underscore, underscore + 1, strlen (underscore + 1) + 1);
|
|
|
|
return stripped;
|
|
}
|
|
|
|
|
|
static void
|
|
set_string (gpointer object,
|
|
const char *id,
|
|
const char *data)
|
|
{
|
|
g_object_set_data_full (object, id, g_strdup (data), g_free);
|
|
}
|
|
|
|
static const char *
|
|
get_string (gpointer object,
|
|
const char *id)
|
|
{
|
|
return g_object_get_data (object, id);
|
|
}
|
|
|
|
|
|
static void
|
|
set_bool (gpointer object,
|
|
const char *id,
|
|
gboolean value)
|
|
{
|
|
g_object_set_data (object, id, GINT_TO_POINTER (value));
|
|
}
|
|
|
|
static gboolean
|
|
get_bool (gpointer object,
|
|
const char *id)
|
|
{
|
|
return g_object_get_data (object, id) != NULL;
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_display_name (MooActionBase *ab,
|
|
const char *name)
|
|
{
|
|
GtkStockItem stock_item;
|
|
char *freeme = NULL;
|
|
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
g_return_if_fail (name != NULL);
|
|
|
|
if (gtk_stock_lookup (name, &stock_item))
|
|
{
|
|
freeme = strip_underscore (stock_item.label);
|
|
name = freeme;
|
|
}
|
|
|
|
set_string (ab, "moo-action-display-name", name);
|
|
g_object_notify (G_OBJECT (ab), "display-name");
|
|
|
|
g_free (freeme);
|
|
}
|
|
|
|
const char *
|
|
_moo_action_get_display_name (gpointer action)
|
|
{
|
|
const char *display_name;
|
|
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), NULL);
|
|
|
|
display_name = get_string (action, "moo-action-display-name");
|
|
|
|
if (!display_name)
|
|
display_name = gtk_action_get_name (action);
|
|
|
|
return display_name;
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_accel (MooActionBase *ab,
|
|
const char *accel)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
|
|
if (accel && !accel[0])
|
|
accel = NULL;
|
|
|
|
set_string (ab, "moo-action-accel", accel);
|
|
g_object_notify (G_OBJECT (ab), "accel");
|
|
}
|
|
|
|
static const char *
|
|
moo_action_base_get_accel (MooActionBase *ab)
|
|
{
|
|
const char *accel;
|
|
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (ab), "");
|
|
|
|
accel = get_string (ab, "moo-action-accel");
|
|
|
|
if (!accel)
|
|
accel = "";
|
|
|
|
return accel;
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_set_no_accel (gpointer action,
|
|
gboolean no_accel)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (action));
|
|
set_bool (action, "moo-action-no-accel", no_accel);
|
|
g_object_notify (G_OBJECT (action), "no-accel");
|
|
}
|
|
|
|
gboolean
|
|
_moo_action_get_no_accel (gpointer action)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), FALSE);
|
|
return get_bool (action, "moo-action-no-accel");
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_force_accel_label (MooActionBase *ab,
|
|
gboolean force)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
set_bool (ab, "moo-action-force-accel-label", force);
|
|
g_object_notify (G_OBJECT (ab), "force-accel-label");
|
|
}
|
|
|
|
static gboolean
|
|
moo_action_base_get_force_accel_label (MooActionBase *ab)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (ab), FALSE);
|
|
return get_bool (ab, "moo-action-force-accel-label");
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_dead (MooActionBase *ab, gboolean dead)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
set_bool (ab, "moo-action-dead", dead);
|
|
g_object_notify (G_OBJECT (ab), "dead");
|
|
}
|
|
|
|
gboolean
|
|
_moo_action_get_dead (gpointer action)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), FALSE);
|
|
return get_bool (action, "moo-action-dead");
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_active (MooActionBase *ab, gboolean active)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
g_object_set (ab, "visible", active, "sensitive", active, NULL);
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_has_submenu (MooActionBase *ab, gboolean has_submenu)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
set_bool (ab, "moo-action-has-submenu", has_submenu);
|
|
g_object_notify (G_OBJECT (ab), "has-submenu");
|
|
}
|
|
|
|
gboolean
|
|
_moo_action_get_has_submenu (gpointer action)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), FALSE);
|
|
return get_bool (action, "moo-action-has-submenu");
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_label (MooActionBase *ab,
|
|
const char *label)
|
|
{
|
|
GtkStockItem stock_item;
|
|
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
|
|
if (label && gtk_stock_lookup (label, &stock_item))
|
|
label = stock_item.label;
|
|
|
|
g_object_set (G_OBJECT (ab), "GtkAction::label", label, NULL);
|
|
}
|
|
|
|
|
|
static void
|
|
moo_action_base_set_tooltip (MooActionBase *ab,
|
|
const char *tooltip)
|
|
{
|
|
GtkStockItem stock_item;
|
|
char *freeme = NULL;
|
|
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (ab));
|
|
|
|
if (tooltip && gtk_stock_lookup (tooltip, &stock_item))
|
|
{
|
|
freeme = strip_underscore (stock_item.label);
|
|
tooltip = freeme;
|
|
}
|
|
|
|
g_object_set (G_OBJECT (ab), "GtkAction::tooltip", tooltip, NULL);
|
|
g_free (freeme);
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_base_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
MooActionBase *ab = MOO_ACTION_BASE (object);
|
|
|
|
switch (property_id)
|
|
{
|
|
case MOO_ACTION_BASE_PROP_DISPLAY_NAME:
|
|
moo_action_base_set_display_name (ab, g_value_get_string (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_ACCEL:
|
|
moo_action_base_set_accel (ab, g_value_get_string (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_NO_ACCEL:
|
|
_moo_action_set_no_accel (ab, g_value_get_boolean (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_FORCE_ACCEL_LABEL:
|
|
moo_action_base_set_force_accel_label (ab, g_value_get_boolean (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_DEAD:
|
|
moo_action_base_set_dead (ab, g_value_get_boolean (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_ACTIVE:
|
|
moo_action_base_set_active (ab, g_value_get_boolean (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_HAS_SUBMENU:
|
|
moo_action_base_set_has_submenu (ab, g_value_get_boolean (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_LABEL:
|
|
moo_action_base_set_label (ab, g_value_get_string (value));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_TOOLTIP:
|
|
moo_action_base_set_tooltip (ab, g_value_get_string (value));
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_base_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
MooActionBase *ab = MOO_ACTION_BASE (object);
|
|
|
|
switch (property_id)
|
|
{
|
|
case MOO_ACTION_BASE_PROP_DISPLAY_NAME:
|
|
g_value_set_string (value, _moo_action_get_display_name (ab));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_ACCEL:
|
|
g_value_set_string (value, moo_action_base_get_accel (ab));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_NO_ACCEL:
|
|
g_value_set_boolean (value, _moo_action_get_no_accel (ab));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_FORCE_ACCEL_LABEL:
|
|
g_value_set_boolean (value, moo_action_base_get_force_accel_label (ab));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_DEAD:
|
|
g_value_set_boolean (value, _moo_action_get_dead (ab));
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_HAS_SUBMENU:
|
|
g_value_set_boolean (value, _moo_action_get_has_submenu (ab));
|
|
break;
|
|
|
|
case MOO_ACTION_BASE_PROP_LABEL:
|
|
g_object_get_property (object, "GtkAction::label", value);
|
|
break;
|
|
case MOO_ACTION_BASE_PROP_TOOLTIP:
|
|
g_object_get_property (object, "GtkAction::tooltip", value);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
|
|
GtkActionGroup *
|
|
_moo_action_get_group (gpointer action)
|
|
{
|
|
GtkActionGroup *group = NULL;
|
|
|
|
g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
|
|
|
|
g_object_get (action, "action-group", &group, NULL);
|
|
|
|
if (group)
|
|
g_object_unref (group);
|
|
|
|
return group;
|
|
}
|
|
|
|
|
|
char *
|
|
_moo_action_make_accel_path (gpointer action)
|
|
{
|
|
GtkActionGroup *group = NULL;
|
|
MooActionCollection *collection;
|
|
const char *name, *group_name, *collection_name;
|
|
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), NULL);
|
|
|
|
group = _moo_action_get_group (action);
|
|
g_return_val_if_fail (MOO_IS_ACTION_GROUP (group), NULL);
|
|
collection = _moo_action_group_get_collection (MOO_ACTION_GROUP (group));
|
|
g_return_val_if_fail (MOO_IS_ACTION_COLLECTION (collection), NULL);
|
|
|
|
name = gtk_action_get_name (action);
|
|
group_name = gtk_action_group_get_name (group);
|
|
collection_name = moo_action_collection_get_name (collection);
|
|
|
|
g_return_val_if_fail (collection_name != NULL, NULL);
|
|
g_return_val_if_fail (name != NULL && name[0] != 0, NULL);
|
|
|
|
if (group_name)
|
|
return g_strdup_printf ("<MooAction>/%s/%s/%s", collection_name, group_name, name);
|
|
else
|
|
return g_strdup_printf ("<MooAction>/%s/%s", collection_name, name);
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_set_accel_path (gpointer action,
|
|
const char *accel_path)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (action));
|
|
gtk_action_set_accel_path (action, accel_path);
|
|
}
|
|
|
|
|
|
const char *
|
|
_moo_action_get_accel_path (gpointer action)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), NULL);
|
|
return gtk_action_get_accel_path (action);
|
|
}
|
|
|
|
|
|
const char *
|
|
_moo_action_get_default_accel (gpointer action)
|
|
{
|
|
g_return_val_if_fail (MOO_IS_ACTION_BASE (action), "");
|
|
return moo_action_base_get_accel (action);
|
|
}
|
|
|
|
|
|
void
|
|
_moo_action_set_default_accel (gpointer action,
|
|
const char *accel)
|
|
{
|
|
g_return_if_fail (MOO_IS_ACTION_BASE (action));
|
|
moo_action_base_set_accel (action, accel);
|
|
}
|