1 /*
2  * Copyright 2012 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, version 3 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors: Ryan Lortie <desrt@desrt.ca>
17  *          William Hua <william.hua@canonical.com>
18  */
19 
20 #include "unity-gtk-action-private.h"
21 
22 G_DEFINE_TYPE(UnityGtkAction, unity_gtk_action, G_TYPE_OBJECT);
23 
unity_gtk_action_dispose(GObject * object)24 static void unity_gtk_action_dispose(GObject *object)
25 {
26 	UnityGtkAction *action;
27 	GHashTable *items_by_name;
28 
29 	g_return_if_fail(UNITY_GTK_IS_ACTION(object));
30 
31 	action        = UNITY_GTK_ACTION(object);
32 	items_by_name = action->items_by_name;
33 
34 	if (items_by_name != NULL)
35 	{
36 		action->items_by_name = NULL;
37 		g_hash_table_unref(items_by_name);
38 	}
39 
40 	unity_gtk_action_set_item(action, NULL);
41 	unity_gtk_action_set_subname(action, NULL);
42 	unity_gtk_action_set_name(action, NULL);
43 
44 	G_OBJECT_CLASS(unity_gtk_action_parent_class)->dispose(object);
45 }
46 
unity_gtk_action_class_init(UnityGtkActionClass * klass)47 static void unity_gtk_action_class_init(UnityGtkActionClass *klass)
48 {
49 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
50 
51 	object_class->dispose = unity_gtk_action_dispose;
52 }
53 
unity_gtk_action_init(UnityGtkAction * self)54 static void unity_gtk_action_init(UnityGtkAction *self)
55 {
56 }
57 
unity_gtk_action_new(const char * name,UnityGtkMenuItem * item)58 UnityGtkAction *unity_gtk_action_new(const char *name, UnityGtkMenuItem *item)
59 {
60 	UnityGtkAction *action = g_object_new(UNITY_GTK_TYPE_ACTION, NULL);
61 
62 	unity_gtk_action_set_name(action, name);
63 	unity_gtk_action_set_item(action, item);
64 
65 	return action;
66 }
67 
unity_gtk_action_new_radio(const char * name)68 UnityGtkAction *unity_gtk_action_new_radio(const char *name)
69 {
70 	UnityGtkAction *action = g_object_new(UNITY_GTK_TYPE_ACTION, NULL);
71 
72 	unity_gtk_action_set_name(action, name);
73 	action->items_by_name =
74 	    g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
75 
76 	return action;
77 }
78 
unity_gtk_action_set_name(UnityGtkAction * action,const char * name)79 void unity_gtk_action_set_name(UnityGtkAction *action, const char *name)
80 {
81 	g_return_if_fail(UNITY_GTK_IS_ACTION(action));
82 
83 	g_free(action->name);
84 	action->name = g_strdup(name);
85 }
86 
unity_gtk_action_set_subname(UnityGtkAction * action,const char * subname)87 void unity_gtk_action_set_subname(UnityGtkAction *action, const char *subname)
88 {
89 	g_return_if_fail(UNITY_GTK_IS_ACTION(action));
90 
91 	g_free(action->subname);
92 	action->subname = g_strdup(subname);
93 }
94 
unity_gtk_action_set_item(UnityGtkAction * action,UnityGtkMenuItem * item)95 void unity_gtk_action_set_item(UnityGtkAction *action, UnityGtkMenuItem *item)
96 {
97 	UnityGtkMenuItem *old_item;
98 
99 	g_return_if_fail(UNITY_GTK_IS_ACTION(action));
100 
101 	old_item = action->item;
102 
103 	if (item != old_item)
104 	{
105 		if (old_item != NULL)
106 		{
107 			action->item = NULL;
108 			g_object_unref(old_item);
109 		}
110 
111 		if (item != NULL)
112 			action->item = g_object_ref(item);
113 	}
114 }
115 
unity_gtk_action_print(UnityGtkAction * action,guint indent)116 void unity_gtk_action_print(UnityGtkAction *action, guint indent)
117 {
118 	char *space;
119 
120 	g_return_if_fail(action == NULL || UNITY_GTK_IS_ACTION(action));
121 
122 	space = g_strnfill(indent, ' ');
123 
124 	if (action != NULL)
125 	{
126 		g_print("%s(%s *) %p\n",
127 		        space,
128 		        G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(action)),
129 		        action);
130 
131 		if (action->name != NULL)
132 			g_print("%s  \"%s\"\n", space, action->name);
133 
134 		if (action->subname != NULL)
135 			g_print("%s  \"%s\"\n", space, action->subname);
136 
137 		if (action->item != NULL)
138 			g_print("%s  (%s *) %p\n",
139 			        space,
140 			        G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(action->item)),
141 			        action->item);
142 
143 		if (action->items_by_name != NULL)
144 		{
145 			GHashTableIter iter;
146 			gpointer key;
147 			gpointer value;
148 
149 			g_hash_table_iter_init(&iter, action->items_by_name);
150 			while (g_hash_table_iter_next(&iter, &key, &value))
151 				g_print("%s  \"%s\" -> (%s *) %p\n",
152 				        space,
153 				        (const char *)key,
154 				        G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(value)),
155 				        value);
156 		}
157 	}
158 	else
159 		g_print("%sNULL\n", space);
160 
161 	g_free(space);
162 }
163