No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-menu-tool-button.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-menu-tool-button.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-menu-tool-button.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-menu-tool-button.h"
27
28 #define E_MENU_TOOL_BUTTON_GET_PRIVATE(obj) \
29 (G_TYPE_INSTANCE_GET_PRIVATE \
30 ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonPrivate))
31
32 struct _EMenuToolButtonPrivate {
33 gchar *prefer_item;
34 };
35
36 enum {
37 PROP_0,
38 PROP_PREFER_ITEM
39 };
40
41 G_DEFINE_TYPE (
42 EMenuToolButton,
43 e_menu_tool_button,
44 GTK_TYPE_MENU_TOOL_BUTTON)
45
46 static GtkWidget *
47 menu_tool_button_clone_image (GtkWidget *source)
48 {
49 GtkIconSize size;
50 GtkImageType image_type;
51 const gchar *icon_name;
52
53 /* XXX This isn't general purpose because it requires that the
54 * source image be using a named icon. Somewhat surprised
55 * GTK+ doesn't offer something like this. */
56 image_type = gtk_image_get_storage_type (GTK_IMAGE (source));
57 g_return_val_if_fail (image_type == GTK_IMAGE_ICON_NAME, NULL);
58 gtk_image_get_icon_name (GTK_IMAGE (source), &icon_name, &size);
59
60 return gtk_image_new_from_icon_name (icon_name, size);
61 }
62
63 static GtkMenuItem *
64 menu_tool_button_get_prefer_menu_item (GtkMenuToolButton *menu_tool_button)
65 {
66 GtkWidget *menu;
67 GtkMenuItem *item = NULL;
68 GList *children;
69 const gchar *prefer_item;
70
71 menu = gtk_menu_tool_button_get_menu (menu_tool_button);
72 if (!GTK_IS_MENU (menu))
73 return NULL;
74
75 children = gtk_container_get_children (GTK_CONTAINER (menu));
76 if (children == NULL)
77 return NULL;
78
79 prefer_item = e_menu_tool_button_get_prefer_item (
80 E_MENU_TOOL_BUTTON (menu_tool_button));
81 if (prefer_item != NULL && *prefer_item != '\0') {
82 GtkAction *action;
83 GList *iter;
84
85 for (iter = children; iter != NULL; iter = iter->next) {
86 item = GTK_MENU_ITEM (iter->data);
87
88 if (!item)
89 continue;
90
91 action = gtk_activatable_get_related_action (
92 GTK_ACTIVATABLE (item));
93 if (action && g_strcmp0 (gtk_action_get_name (action), prefer_item) == 0)
94 break;
95 else if (!action && g_strcmp0 (gtk_widget_get_name (GTK_WIDGET (item)), prefer_item) == 0)
96 break;
97
98 item = NULL;
99 }
100 }
101
102 if (!item)
103 item = GTK_MENU_ITEM (children->data);
104
105 g_list_free (children);
106
107 return item;
108 }
109
110 static void
111 menu_tool_button_update_button (GtkToolButton *tool_button)
112 {
113 GtkMenuItem *menu_item;
114 GtkMenuToolButton *menu_tool_button;
115 GtkImageMenuItem *image_menu_item;
116 GtkAction *action;
117 GtkWidget *image;
118 gchar *tooltip = NULL;
119
120 menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button);
121 menu_item = menu_tool_button_get_prefer_menu_item (menu_tool_button);
122 if (!GTK_IS_IMAGE_MENU_ITEM (menu_item))
123 return;
124
125 image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item);
126 image = gtk_image_menu_item_get_image (image_menu_item);
127 if (!GTK_IS_IMAGE (image))
128 return;
129
130 image = menu_tool_button_clone_image (image);
131 gtk_tool_button_set_icon_widget (tool_button, image);
132 gtk_widget_show (image);
133
134 /* If the menu item is a proxy for a GtkAction, extract
135 * the action's tooltip and use it as our own tooltip. */
136 action = gtk_activatable_get_related_action (
137 GTK_ACTIVATABLE (menu_item));
138 if (action != NULL)
139 g_object_get (action, "tooltip", &tooltip, NULL);
140 gtk_widget_set_tooltip_text (GTK_WIDGET (tool_button), tooltip);
141 g_free (tooltip);
142 }
143
144 static void
145 menu_tool_button_clicked (GtkToolButton *tool_button)
146 {
147 GtkMenuItem *menu_item;
148 GtkMenuToolButton *menu_tool_button;
149
150 menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button);
151 menu_item = menu_tool_button_get_prefer_menu_item (menu_tool_button);
152
153 if (GTK_IS_MENU_ITEM (menu_item))
154 gtk_menu_item_activate (menu_item);
155 }
156
157 static void
158 menu_tool_button_set_property (GObject *object,
159 guint property_id,
160 const GValue *value,
161 GParamSpec *pspec)
162 {
163 switch (property_id) {
164 case PROP_PREFER_ITEM:
165 e_menu_tool_button_set_prefer_item (
166 E_MENU_TOOL_BUTTON (object),
167 g_value_get_string (value));
168 return;
169 }
170
171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
172 }
173
174 static void
175 menu_tool_button_get_property (GObject *object,
176 guint property_id,
177 GValue *value,
178 GParamSpec *pspec)
179 {
180 switch (property_id) {
181 case PROP_PREFER_ITEM:
182 g_value_set_string (
183 value, e_menu_tool_button_get_prefer_item (
184 E_MENU_TOOL_BUTTON (object)));
185 return;
186 }
187
188 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
189 }
190
191 static void
192 menu_tool_button_dispose (GObject *object)
193 {
194 EMenuToolButtonPrivate *priv = E_MENU_TOOL_BUTTON (object)->priv;
195
196 if (priv->prefer_item) {
197 g_free (priv->prefer_item);
198 priv->prefer_item = NULL;
199 }
200
201 /* Chain up to parent's dispose() method. */
202 G_OBJECT_CLASS (e_menu_tool_button_parent_class)->dispose (object);
203 }
204
205 static void
206 e_menu_tool_button_class_init (EMenuToolButtonClass *class)
207 {
208 GObjectClass *object_class;
209 GtkToolButtonClass *tool_button_class;
210
211 g_type_class_add_private (class, sizeof (EMenuToolButtonPrivate));
212
213 object_class = G_OBJECT_CLASS (class);
214 object_class->set_property = menu_tool_button_set_property;
215 object_class->get_property = menu_tool_button_get_property;
216 object_class->dispose = menu_tool_button_dispose;
217
218 tool_button_class = GTK_TOOL_BUTTON_CLASS (class);
219 tool_button_class->clicked = menu_tool_button_clicked;
220
221 g_object_class_install_property (
222 object_class,
223 PROP_PREFER_ITEM,
224 g_param_spec_string (
225 "prefer-item",
226 "Prefer Item",
227 "Name of an item to show instead of the first",
228 NULL,
229 G_PARAM_READWRITE));
230 }
231
232 static void
233 e_menu_tool_button_init (EMenuToolButton *button)
234 {
235 button->priv = E_MENU_TOOL_BUTTON_GET_PRIVATE (button);
236
237 button->priv->prefer_item = NULL;
238
239 g_signal_connect (
240 button, "notify::menu",
241 G_CALLBACK (menu_tool_button_update_button), NULL);
242 }
243
244 GtkToolItem *
245 e_menu_tool_button_new (const gchar *label)
246 {
247 return g_object_new (E_TYPE_MENU_TOOL_BUTTON, "label", label, NULL);
248 }
249
250 void
251 e_menu_tool_button_set_prefer_item (EMenuToolButton *button,
252 const gchar *prefer_item)
253 {
254 g_return_if_fail (button != NULL);
255 g_return_if_fail (E_IS_MENU_TOOL_BUTTON (button));
256
257 if (g_strcmp0 (button->priv->prefer_item, prefer_item) == 0)
258 return;
259
260 g_free (button->priv->prefer_item);
261 button->priv->prefer_item = g_strdup (prefer_item);
262
263 g_object_notify (G_OBJECT (button), "prefer-item");
264 }
265
266 const gchar *
267 e_menu_tool_button_get_prefer_item (EMenuToolButton *button)
268 {
269 g_return_val_if_fail (button != NULL, NULL);
270 g_return_val_if_fail (E_IS_MENU_TOOL_BUTTON (button), NULL);
271
272 return button->priv->prefer_item;
273 }