1 /*-
2  * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 2 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16  * Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21 
22 #include <glib/gi18n-lib.h>
23 
24 #include <thunarx/thunarx-private.h>
25 #include <thunarx/thunarx-menu-item.h>
26 #include <thunarx/thunarx-menu.h>
27 
28 
29 
30 /**
31  * SECTION: thunarx-menu-item
32  * @short_description: The base class for menu items added to the context menus
33  * @title: ThunarxMenuItem
34  * @include: thunarx/thunarx.h
35  *
36  * The class for menu items that can be added to Thunar's context menus
37  * by extensions implementing the #ThunarxMenuProvider, #ThunarxPreferencesProvider
38  * or #ThunarxRenamerProvider interfaces. The items returned by extensions from
39  * *_get_menu_items() methods are instances of this class or a derived class.
40  */
41 
42 /* Signal identifiers */
43 enum
44 {
45   ACTIVATE,
46   LAST_SIGNAL
47 };
48 
49 /* Property identifiers */
50 enum
51 {
52   PROP_0,
53   PROP_NAME,
54   PROP_LABEL,
55   PROP_TOOLTIP,
56   PROP_ICON,
57   PROP_SENSITIVE,
58   PROP_PRIORITY,
59   PROP_MENU,
60   LAST_PROP
61 };
62 
63 
64 
65 static void thunarx_menu_item_get_property (GObject      *object,
66                                             guint         param_id,
67                                             GValue       *value,
68                                             GParamSpec   *pspec);
69 static void thunarx_menu_item_set_property (GObject      *object,
70                                             guint         param_id,
71                                             const GValue *value,
72                                             GParamSpec   *pspec);
73 static void thunarx_menu_item_finalize     (GObject      *object);
74 
75 
76 
77 struct _ThunarxMenuItemPrivate
78 {
79   gchar       *name;
80   gchar       *label;
81   gchar       *tooltip;
82   gchar       *icon;
83   gboolean     sensitive;
84   gboolean     priority;
85   ThunarxMenu *menu;
86 };
87 
88 
89 
90 static guint signals[LAST_SIGNAL];
91 
92 
93 
G_DEFINE_TYPE_WITH_PRIVATE(ThunarxMenuItem,thunarx_menu_item,G_TYPE_OBJECT)94 G_DEFINE_TYPE_WITH_PRIVATE (ThunarxMenuItem, thunarx_menu_item, G_TYPE_OBJECT)
95 
96 
97 
98 static void
99 thunarx_menu_item_class_init (ThunarxMenuItemClass *klass)
100 {
101   GObjectClass *gobject_class;
102 
103   gobject_class = G_OBJECT_CLASS (klass);
104   gobject_class->finalize = thunarx_menu_item_finalize;
105   gobject_class->get_property = thunarx_menu_item_get_property;
106   gobject_class->set_property = thunarx_menu_item_set_property;
107 
108   signals[ACTIVATE] =
109       g_signal_new ("activate",
110                     G_TYPE_FROM_CLASS (klass),
111                     G_SIGNAL_RUN_LAST,
112                     G_STRUCT_OFFSET (ThunarxMenuItemClass,
113                                      activate),
114                     NULL, NULL,
115                     g_cclosure_marshal_VOID__VOID,
116                     G_TYPE_NONE, 0);
117 
118   g_object_class_install_property (gobject_class,
119                                    PROP_NAME,
120                                    g_param_spec_string ("name",
121                                                         "Name",
122                                                         "Name of the item",
123                                                         NULL,
124                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE));
125   g_object_class_install_property (gobject_class,
126                                    PROP_LABEL,
127                                    g_param_spec_string ("label",
128                                                         "Label",
129                                                         "Label to display to the user",
130                                                         NULL,
131                                                         G_PARAM_READWRITE));
132   g_object_class_install_property (gobject_class,
133                                    PROP_TOOLTIP,
134                                    g_param_spec_string ("tooltip",
135                                                         "Tooltip",
136                                                         "Tooltip for the menu item",
137                                                         NULL,
138                                                         G_PARAM_READWRITE));
139   g_object_class_install_property (gobject_class,
140                                    PROP_ICON,
141                                    g_param_spec_string ("icon",
142                                                         "Icon",
143                                                         "Textual representation of the icon (as returned "
144                                                         "by g_icon_to_string()) to display in the menu item",
145                                                         NULL,
146                                                         G_PARAM_READWRITE));
147   g_object_class_install_property (gobject_class,
148                                    PROP_SENSITIVE,
149                                    g_param_spec_boolean ("sensitive",
150                                                          "Sensitive",
151                                                          "Whether the menu item is sensitive",
152                                                          TRUE,
153                                                          G_PARAM_READWRITE));
154   g_object_class_install_property (gobject_class,
155                                    PROP_PRIORITY,
156                                    g_param_spec_boolean ("priority",
157                                                          "Priority",
158                                                          "Show priority text in toolbars",
159                                                          TRUE,
160                                                          G_PARAM_READWRITE));
161   g_object_class_install_property (gobject_class,
162                                    PROP_MENU,
163                                    g_param_spec_object ("menu",
164                                                         "Menu",
165                                                         "The menu belonging to this item. May be null.",
166                                                         THUNARX_TYPE_MENU,
167                                                         G_PARAM_READWRITE));
168 }
169 
170 
171 
172 static void
thunarx_menu_item_init(ThunarxMenuItem * item)173 thunarx_menu_item_init (ThunarxMenuItem *item)
174 {
175   item->priv = thunarx_menu_item_get_instance_private (item);
176   item->priv->sensitive = TRUE;
177   item->priv->priority = FALSE;
178   item->priv->menu = NULL;
179 }
180 
181 
182 
183 static void
thunarx_menu_item_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)184 thunarx_menu_item_get_property (GObject    *object,
185                                 guint       param_id,
186                                 GValue     *value,
187                                 GParamSpec *pspec)
188 {
189   ThunarxMenuItem *item = THUNARX_MENU_ITEM (object);
190 
191   switch (param_id)
192     {
193       case PROP_NAME:
194         g_value_set_string (value, item->priv->name);
195         break;
196 
197       case PROP_LABEL:
198         g_value_set_string (value, item->priv->label);
199         break;
200 
201       case PROP_TOOLTIP:
202         g_value_set_string (value, item->priv->tooltip);
203         break;
204 
205       case PROP_ICON:
206         g_value_set_string (value, item->priv->icon);
207         break;
208 
209       case PROP_SENSITIVE:
210         g_value_set_boolean (value, item->priv->sensitive);
211         break;
212 
213       case PROP_PRIORITY:
214         g_value_set_boolean (value, item->priv->priority);
215         break;
216 
217       case PROP_MENU:
218         g_value_set_object (value, item->priv->menu);
219         break;
220 
221       default:
222         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
223         break;
224      }
225 }
226 
227 
228 
229 static void
thunarx_menu_item_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)230 thunarx_menu_item_set_property (GObject      *object,
231                                 guint         param_id,
232                                 const GValue *value,
233                                 GParamSpec   *pspec)
234 {
235   ThunarxMenuItem *item = THUNARX_MENU_ITEM (object);
236 
237   switch (param_id)
238     {
239       case PROP_NAME:
240         g_free (item->priv->name);
241         item->priv->name = g_strdup (g_value_get_string (value));
242         g_object_notify (object, "name");
243         break;
244 
245       case PROP_LABEL:
246         g_free (item->priv->label);
247         item->priv->label = g_strdup (g_value_get_string (value));
248         g_object_notify (object, "label");
249         break;
250 
251       case PROP_TOOLTIP:
252         g_free (item->priv->tooltip);
253         item->priv->tooltip = g_strdup (g_value_get_string (value));
254         g_object_notify (object, "tooltip");
255         break;
256 
257       case PROP_ICON:
258         g_free (item->priv->icon);
259         item->priv->icon = g_strdup (g_value_get_string (value));
260         g_object_notify (object, "icon");
261         break;
262 
263       case PROP_SENSITIVE:
264         item->priv->sensitive = g_value_get_boolean (value);
265         g_object_notify (object, "sensitive");
266         break;
267 
268       case PROP_PRIORITY:
269         item->priv->priority = g_value_get_boolean (value);
270         g_object_notify (object, "priority");
271         break;
272 
273       case PROP_MENU:
274         if (item->priv->menu)
275           g_object_unref (item->priv->menu);
276         item->priv->menu = g_object_ref (g_value_get_object (value));
277         g_object_notify (object, "menu");
278         break;
279 
280       default:
281         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
282         break;
283     }
284 }
285 
286 
287 
288 static void
thunarx_menu_item_finalize(GObject * object)289 thunarx_menu_item_finalize (GObject *object)
290 {
291   ThunarxMenuItem *item = THUNARX_MENU_ITEM (object);
292 
293   g_free (item->priv->name);
294   g_free (item->priv->label);
295   g_free (item->priv->tooltip);
296   g_free (item->priv->icon);
297 
298   if (item->priv->menu)
299     g_object_unref (item->priv->menu);
300 
301   (*G_OBJECT_CLASS (thunarx_menu_item_parent_class)->finalize) (object);
302 }
303 
304 
305 
306 /**
307  * thunarx_menu_item_new:
308  * @name: identifier for the menu item
309  * @label: user-visible label of the menu item
310  * @tooltip: tooltip of the menu item
311  * @icon: textual representation of the icon to display in the menu
312  *        item, as returned by g_icon_to_string(). A path or icon name
313  *        are valid representations too.
314  *
315  * Creates a new menu item that can be added to the toolbar or to a contextual menu.
316  *
317  * Returns: a newly created #ThunarxMenuItem
318  */
319 ThunarxMenuItem *
thunarx_menu_item_new(const gchar * name,const gchar * label,const gchar * tooltip,const gchar * icon)320 thunarx_menu_item_new (const gchar *name,
321                        const gchar *label,
322                        const gchar *tooltip,
323                        const gchar *icon)
324 {
325   g_return_val_if_fail (name != NULL, NULL);
326   g_return_val_if_fail (label != NULL, NULL);
327 
328   return g_object_new (THUNARX_TYPE_MENU_ITEM,
329                        "name", name,
330                        "label", label,
331                        "tooltip", tooltip,
332                        "icon", icon,
333                        NULL);
334 }
335 
336 
337 
338 /**
339  * thunarx_menu_item_activate:
340  * @item: pointer to a #ThunarxMenuItem instance
341  *
342  * Emits the activate signal.
343  */
344 void
thunarx_menu_item_activate(ThunarxMenuItem * item)345 thunarx_menu_item_activate (ThunarxMenuItem *item)
346 {
347   g_signal_emit (item, signals[ACTIVATE], 0);
348 }
349 
350 
351 
352 /**
353  * thunarx_menu_item_get_sensitive:
354  * @item: pointer to a #ThunarxMenuItem instance
355  *
356  * Returns whether the menu item is sensitive.
357  */
358 gboolean
thunarx_menu_item_get_sensitive(ThunarxMenuItem * item)359 thunarx_menu_item_get_sensitive (ThunarxMenuItem *item)
360 {
361   g_return_val_if_fail (THUNARX_IS_MENU_ITEM (item), FALSE);
362   return item->priv->sensitive;
363 }
364 
365 
366 
367 /**
368  * thunarx_menu_item_set_sensitive:
369  * @item: pointer to a #ThunarxMenuItem instance
370  * @sensitive: %TRUE to make the menu item sensitive
371  *
372  * Sets the ::sensitive property of the menu item to @sensitive.
373  */
374 void
thunarx_menu_item_set_sensitive(ThunarxMenuItem * item,gboolean sensitive)375 thunarx_menu_item_set_sensitive (ThunarxMenuItem *item,
376                                  gboolean         sensitive)
377 {
378   g_return_if_fail (THUNARX_IS_MENU_ITEM (item));
379   item->priv->sensitive = sensitive;
380 }
381 
382 
383 
384 /**
385  * thunarx_menu_item_set_menu:
386  * @item: pointer to a #ThunarxMenuItem instance
387  * @menu: pointer to a #ThunarxMenu instance
388  *
389  * Attaches @menu to menu item.
390  */
391 void
thunarx_menu_item_set_menu(ThunarxMenuItem * item,ThunarxMenu * menu)392 thunarx_menu_item_set_menu (ThunarxMenuItem *item,
393                             ThunarxMenu     *menu)
394 {
395   g_return_if_fail (THUNARX_IS_MENU_ITEM (item));
396   g_return_if_fail (THUNARX_IS_MENU (menu));
397 
398   g_object_set (item, "menu", THUNARX_MENU (menu), NULL);
399 }
400 
401 
402 
403 /**
404  * thunarx_menu_item_list_free:
405  * @items: (element-type ThunarxMenuItem): a list of #ThunarxMenuItem
406  */
407 void
thunarx_menu_item_list_free(GList * items)408 thunarx_menu_item_list_free (GList *items)
409 {
410   g_return_if_fail (items != NULL);
411 
412   g_list_foreach (items, (GFunc) (void (*)(void)) g_object_unref, NULL);
413   g_list_free (items);
414 }
415