[Xfce4-commits] [xfce/garcon] 06/12: Added desktop actions support (bug #11268)

noreply at xfce.org noreply at xfce.org
Fri Jun 3 07:52:03 CEST 2016


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository xfce/garcon.

commit aec77533132eb324180ef771e15226a752573eae
Author: Danila Poyarkov <dannotemail at gmail.com>
Date:   Wed Jun 1 19:55:22 2016 +0300

    Added desktop actions support (bug #11268)
    
    * Minor changes by Eric, mostly dropping the changes
    to the test-display-menu since it has changed and
    fixing a couple g_return_if_fail macros which needed
    to be g_return_val_if_fail.
    
    Signed-off-by: Eric Koegel <eric.koegel at gmail.com>
---
 garcon/Makefile.am               |   2 +
 garcon/garcon-menu-item-action.c | 249 ++++++++++++++++++++++++++++++++
 garcon/garcon-menu-item-action.h |  74 ++++++++++
 garcon/garcon-menu-item.c        | 303 +++++++++++++++++++++++++++++++++------
 garcon/garcon-menu-item.h        | 128 +++++++++--------
 garcon/garcon.h                  |   1 +
 6 files changed, 651 insertions(+), 106 deletions(-)

diff --git a/garcon/Makefile.am b/garcon/Makefile.am
index c9941b1..d57e0ca 100644
--- a/garcon/Makefile.am
+++ b/garcon/Makefile.am
@@ -43,6 +43,7 @@ libgarcon_headers =							\
 	garcon-menu-element.h						\
 	garcon-menu-separator.h						\
 	garcon-menu-directory.h						\
+	garcon-menu-item-action.h						\
 	garcon-menu-item-pool.h						\
 	garcon-menu-item-cache.h					\
 	garcon-environment.h						\
@@ -59,6 +60,7 @@ libgarcon_sources =							\
 	garcon-menu-element.c						\
 	garcon-menu-separator.c						\
 	garcon-menu-directory.c						\
+	garcon-menu-item-action.c						\
 	garcon-menu-item-pool.c						\
 	garcon-menu-item-cache.c					\
 	garcon-environment.c						\
diff --git a/garcon/garcon-menu-item-action.c b/garcon/garcon-menu-item-action.c
new file mode 100644
index 0000000..b416895
--- /dev/null
+++ b/garcon/garcon-menu-item-action.c
@@ -0,0 +1,249 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2015 Danila Poyarkov <dannotemail at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include <garcon/garcon-environment.h>
+#include <garcon/garcon-menu-item-action.h>
+#include <garcon/garcon-private.h>
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+  PROP_NAME,
+  PROP_COMMAND,
+};
+
+static void garcon_menu_item_action_finalize     (GObject       *object);
+static void garcon_menu_item_action_get_property (GObject       *object,
+                                                  guint          prop_id,
+                                                  GValue        *value,
+                                                  GParamSpec    *pspec);
+static void garcon_menu_item_action_set_property (GObject       *object,
+                                                  guint          prop_id,
+                                                  const GValue  *value,
+                                                  GParamSpec    *pspec);
+
+struct _GarconMenuItemActionPrivate
+{
+  /* Name to be displayed for the action */
+  gchar *name;
+
+  /* Command to be executed when the action is clicked */
+  gchar *command;
+};
+
+G_DEFINE_TYPE (GarconMenuItemAction, garcon_menu_item_action, G_TYPE_OBJECT)
+
+static void
+garcon_menu_item_action_class_init (GarconMenuItemActionClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  g_type_class_add_private (klass, sizeof (GarconMenuItemActionPrivate));
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = garcon_menu_item_action_finalize;
+  gobject_class->get_property = garcon_menu_item_action_get_property;
+  gobject_class->set_property = garcon_menu_item_action_set_property;
+
+  /**
+   * GarconMenuItemAction:name:
+   *
+   * Name of the application action (will be displayed in menus etc.).
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_NAME,
+                                   g_param_spec_string ("name",
+                                                        "Name",
+                                                        "Name of the action",
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GarconMenuItemAction:command:
+   *
+   * Command to be executed when the application action is clicked.
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_COMMAND,
+                                   g_param_spec_string ("command",
+                                                        "Command",
+                                                        "Application command",
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_STATIC_STRINGS));
+}
+
+static void
+garcon_menu_item_action_init (GarconMenuItemAction *action)
+{
+  action->priv = G_TYPE_INSTANCE_GET_PRIVATE (action, GARCON_TYPE_MENU_ITEM_ACTION, GarconMenuItemActionPrivate);
+}
+
+
+
+static void
+garcon_menu_item_action_finalize (GObject *object)
+{
+  GarconMenuItemAction *action = GARCON_MENU_ITEM_ACTION (object);
+
+  g_free (action->priv->name);
+  g_free (action->priv->command);
+  
+  (*G_OBJECT_CLASS (garcon_menu_item_action_parent_class)->finalize) (object);
+}
+
+
+
+static void
+garcon_menu_item_action_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  GarconMenuItemAction *action = GARCON_MENU_ITEM_ACTION (object);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      g_value_set_string (value, garcon_menu_item_action_get_name (action));
+      break;
+
+    case PROP_COMMAND:
+      g_value_set_string (value, garcon_menu_item_action_get_command (action));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+garcon_menu_item_action_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  GarconMenuItemAction *action = GARCON_MENU_ITEM_ACTION (object);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      garcon_menu_item_action_set_name (action, g_value_get_string (value));
+      break;
+
+    case PROP_COMMAND:
+      garcon_menu_item_action_set_command (action, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+const gchar*
+garcon_menu_item_action_get_name (GarconMenuItemAction *action)
+{
+  g_return_val_if_fail (GARCON_IS_MENU_ITEM_ACTION (action), NULL);
+  return action->priv->name;
+}
+
+
+
+void
+garcon_menu_item_action_set_name (GarconMenuItemAction *action,
+                                  const gchar          *name)
+{
+  g_return_if_fail (GARCON_IS_MENU_ITEM_ACTION (action));
+  g_return_if_fail (g_utf8_validate (name, -1, NULL));
+
+  /* Abort if old and new name are equal */
+  if (g_strcmp0 (action->priv->name, name) == 0)
+    return;
+
+  /* Assign new name */
+  g_free (action->priv->name);
+  action->priv->name = g_strdup (name);
+
+  /* Notify listeners */
+  g_object_notify (G_OBJECT (action), "name");
+}
+
+
+const gchar*
+garcon_menu_item_action_get_command (GarconMenuItemAction *action)
+{
+  g_return_val_if_fail (GARCON_IS_MENU_ITEM_ACTION (action), NULL);
+  return action->priv->command;
+}
+
+
+
+void
+garcon_menu_item_action_set_command (GarconMenuItemAction *action,
+                                     const gchar          *command)
+{
+  g_return_if_fail (GARCON_IS_MENU_ITEM_ACTION (action));
+  g_return_if_fail (command != NULL);
+
+  /* Abort if old and new command are equal */
+  if (g_strcmp0 (action->priv->command, command) == 0)
+    return;
+
+  /* Assign new command */
+  g_free (action->priv->command);
+  action->priv->command = g_strdup (command);
+
+  /* Notify listeners */
+  g_object_notify (G_OBJECT (action), "command");
+}
+
+void
+garcon_menu_item_action_ref (GarconMenuItemAction *action)
+{
+  g_return_if_fail (GARCON_IS_MENU_ITEM_ACTION (action));
+
+  /* Grab a reference on the object */
+  g_object_ref (G_OBJECT (action));
+}
+
+
+
+void
+garcon_menu_item_action_unref (GarconMenuItemAction *action)
+{
+  g_return_if_fail (GARCON_IS_MENU_ITEM_ACTION (action));
+
+  /* Decrement the reference counter */
+  g_object_unref (G_OBJECT (action));
+}
\ No newline at end of file
diff --git a/garcon/garcon-menu-item-action.h b/garcon/garcon-menu-item-action.h
new file mode 100644
index 0000000..2069aaa
--- /dev/null
+++ b/garcon/garcon-menu-item-action.h
@@ -0,0 +1,74 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2015 Danila Poyarkov <dannotemail at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+ #if !defined(GARCON_INSIDE_GARCON_H) && !defined(GARCON_COMPILATION)
+#error "Only <garcon/garcon.h> can be included directly. This file may disappear or change contents."
+#endif
+
+#ifndef __GARCON_MENU_ITEM_ACTION_H__
+#define __GARCON_MENU_ITEM_ACTION_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GarconMenuItemActionPrivate GarconMenuItemActionPrivate;
+typedef struct _GarconMenuItemActionClass   GarconMenuItemActionClass;
+typedef struct _GarconMenuItemAction        GarconMenuItemAction;
+
+#define GARCON_TYPE_MENU_ITEM_ACTION            (garcon_menu_item_action_get_type())
+#define GARCON_MENU_ITEM_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GARCON_TYPE_MENU_ITEM_ACTION, GarconMenuItemAction))
+#define GARCON_MENU_ITEM_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GARCON_TYPE_MENU_ITEM_ACTION, GarconMenuItemActionClass))
+#define GARCON_IS_MENU_ITEM_ACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GARCON_TYPE_MENU_ITEM_ACTION))
+#define GARCON_IS_MENU_ITEM_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GARCON_TYPE_MENU_ITEM_ACTION))
+#define GARCON_MENU_ITEM_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GARCON_TYPE_MENU_ITEM_ACTION, GarconMenuItemActionClass))
+
+struct _GarconMenuItemActionClass
+{
+  GObjectClass __parent__;
+
+  /* signals */
+  void (*changed) (GarconMenuItemAction *action);
+};
+
+struct _GarconMenuItemAction
+{
+  GObject                  __parent__;
+
+  /* < private > */
+  GarconMenuItemActionPrivate *priv;
+};
+
+GType                 garcon_menu_item_action_get_type           (void) G_GNUC_CONST;
+GarconMenuItemAction *garcon_menu_item_action_new                (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+const gchar          *garcon_menu_item_action_get_command        (GarconMenuItemAction  *action);
+void                  garcon_menu_item_action_set_command        (GarconMenuItemAction  *action,
+                                                                  const gchar           *command);
+const gchar          *garcon_menu_item_action_get_name           (GarconMenuItemAction  *action);
+void                  garcon_menu_item_action_set_name           (GarconMenuItemAction  *action,
+                                                                  const gchar           *name);
+void                  garcon_menu_item_action_ref                (GarconMenuItemAction  *action);
+void                  garcon_menu_item_action_unref              (GarconMenuItemAction  *action);
+
+G_END_DECLS
+
+#endif /* !__GARCON_MENU_ITEM_ACTION_H__ */
\ No newline at end of file
diff --git a/garcon/garcon-menu-item.c b/garcon/garcon-menu-item.c
index 66a86bf..3f6f676 100644
--- a/garcon/garcon-menu-item.c
+++ b/garcon/garcon-menu-item.c
@@ -2,6 +2,7 @@
 /*-
  * Copyright (c) 2006-2010 Jannis Pohlmann <jannis at xfce.org>
  * Copyright (c) 2009-2010 Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2015      Danila Poyarkov <dannotemail at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -29,6 +30,7 @@
 #include <garcon/garcon-environment.h>
 #include <garcon/garcon-menu-element.h>
 #include <garcon/garcon-menu-item.h>
+#include <garcon/garcon-menu-item-action.h>
 #include <garcon/garcon-private.h>
 
 
@@ -91,57 +93,60 @@ static guint item_signals[LAST_SIGNAL];
 struct _GarconMenuItemPrivate
 {
   /* Source file of the menu item */
-  GFile    *file;
+  GFile      *file;
 
   /* Desktop file id */
-  gchar    *desktop_id;
+  gchar      *desktop_id;
 
   /* List of categories */
-  GList    *categories;
+  GList      *categories;
 
   /* Whether this application requires a terminal to be started in */
-  guint     requires_terminal : 1;
+  guint       requires_terminal : 1;
 
   /* Whether this menu item should be hidden */
-  guint     no_display : 1;
+  guint       no_display : 1;
 
   /* Whether this application supports startup notification */
-  guint     supports_startup_notification : 1;
+  guint       supports_startup_notification : 1;
 
   /* Name to be displayed for the menu item */
-  gchar    *name;
+  gchar      *name;
 
   /* Generic name of the menu item */
-  gchar    *generic_name;
+  gchar      *generic_name;
 
   /* Comment/description of the item */
-  gchar    *comment;
+  gchar      *comment;
 
   /* Command to be executed when the menu item is clicked */
-  gchar    *command;
+  gchar      *command;
 
   /* TryExec value */
-  gchar    *try_exec;
+  gchar      *try_exec;
 
   /* Menu item icon name */
-  gchar    *icon_name;
+  gchar      *icon_name;
 
   /* Environments in which the menu item should be displayed only */
-  gchar   **only_show_in;
+  gchar     **only_show_in;
 
   /* Environments in which the menu item should be hidden */
-  gchar   **not_show_in;
+  gchar     **not_show_in;
 
   /* Working directory */
-  gchar    *path;
+  gchar      *path;
+
+  /* Hash table for mapping action names to GarconMenuItemAction's */
+  GHashTable *actions;
 
   /* Hidden value */
-  guint     hidden : 1;
+  guint       hidden : 1;
 
   /* Counter keeping the number of menus which use this item. This works
    * like a reference counter and should be increased / decreased by GarconMenu
    * items whenever the item is added to or removed from the menu. */
-  guint     num_allocated;
+  guint       num_allocated;
 };
 
 
@@ -389,6 +394,8 @@ static void
 garcon_menu_item_init (GarconMenuItem *item)
 {
   item->priv = G_TYPE_INSTANCE_GET_PRIVATE (item, GARCON_TYPE_MENU_ITEM, GarconMenuItemPrivate);
+  item->priv->actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+                                               (GDestroyNotify) garcon_menu_item_action_unref);
 }
 
 
@@ -415,6 +422,8 @@ garcon_menu_item_finalize (GObject *object)
   if (item->priv->file != NULL)
     g_object_unref (G_OBJECT (item->priv->file));
 
+  g_hash_table_unref (item->priv->actions);
+
   (*G_OBJECT_CLASS (garcon_menu_item_parent_class)->finalize) (object);
 }
 
@@ -700,24 +709,26 @@ garcon_menu_item_url_exec (XfceRc *rc)
 GarconMenuItem *
 garcon_menu_item_new (GFile *file)
 {
-  GarconMenuItem *item = NULL;
-  XfceRc         *rc;
-  GList          *categories = NULL;
-  gchar          *filename;
-  gboolean        terminal;
-  gboolean        no_display;
-  gboolean        startup_notify;
-  gboolean        hidden;
-  const gchar    *path;
-  const gchar    *name;
-  const gchar    *generic_name;
-  const gchar    *comment;
-  const gchar    *exec;
-  const gchar    *try_exec;
-  const gchar    *icon;
-  gchar         **mt;
-  gchar         **str_list;
-  gchar          *url_exec = NULL;
+  GarconMenuItem       *item = NULL;
+  GarconMenuItemAction *action = NULL;
+  XfceRc               *rc;
+  GList                *categories = NULL;
+  gchar                *filename;
+  gboolean              terminal;
+  gboolean              no_display;
+  gboolean              startup_notify;
+  gboolean              hidden;
+  const gchar          *path;
+  const gchar          *name;
+  const gchar          *generic_name;
+  const gchar          *comment;
+  const gchar          *exec;
+  const gchar          *try_exec;
+  const gchar          *icon;
+  gchar                *action_group;
+  gchar               **mt;
+  gchar               **str_list;
+  gchar                *url_exec = NULL;
 
   g_return_val_if_fail (G_IS_FILE (file), NULL);
   g_return_val_if_fail (g_file_is_native (file), NULL);
@@ -793,6 +804,79 @@ garcon_menu_item_new (GFile *file)
       /* Set the rest of the private data directly */
       item->priv->only_show_in = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, ";");
       item->priv->not_show_in = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, ";");
+
+      /* Determine this application actions */
+      str_list = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_ACTIONS, ";");
+      if (G_LIKELY (str_list != NULL))
+        {
+          for (mt = str_list; *mt != NULL; ++mt)
+            {
+              if (**mt != '\0')
+                {
+                  /* Set current desktop action group */
+                  action_group = g_strdup_printf ("Desktop Action %s", *mt);
+                  xfce_rc_set_group (rc, action_group);
+
+                  /* Parse name and exec command */
+                  name = xfce_rc_read_entry (rc, G_KEY_FILE_DESKTOP_KEY_NAME, NULL);
+                  exec = xfce_rc_read_entry_untranslated (rc, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
+
+                  /* Validate Name and Exec fields */
+                  if (G_LIKELY (exec != NULL && name != NULL))
+                    {
+                      /* Allocate a new action instance */
+                      action = g_object_new (GARCON_TYPE_MENU_ITEM_ACTION,
+                                             "name", name,
+                                             "command", exec,
+                                             NULL);
+
+                      garcon_menu_item_set_action (item, *mt, action);
+                    }
+
+                  g_free (action_group);
+                }
+              else
+                g_free (*mt);
+            }
+
+          /* Cleanup */
+          g_free (str_list);
+        }
+
+      else
+        {
+          str_list = xfce_rc_read_list_entry (rc, "X-Ayatana-Desktop-Shortcuts", ";");
+          if (G_LIKELY (str_list != NULL))
+            {
+              for (mt = str_list; *mt != NULL; ++mt)
+                {
+                  if (**mt != '\0')
+                    {
+                      action_group = g_strdup_printf ("%s Shortcut Group", *mt);
+                      xfce_rc_set_group (rc, action_group);
+
+                      name = xfce_rc_read_entry (rc, G_KEY_FILE_DESKTOP_KEY_NAME, NULL);
+                      exec = xfce_rc_read_entry_untranslated (rc, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
+
+                      if (G_LIKELY (exec != NULL && name != NULL))
+                        {
+                          action = g_object_new (GARCON_TYPE_MENU_ITEM_ACTION,
+                                                 "name", name,
+                                                 "command", exec,
+                                                 NULL);
+
+                          garcon_menu_item_set_action (item, *mt, action);
+                        }
+
+                      g_free (action_group);
+                    }
+                  else
+                    g_free (*mt);
+                }
+
+              g_free (str_list);
+            }
+        }
     }
 
   /* Cleanup */
@@ -857,18 +941,20 @@ garcon_menu_item_reload_from_file (GarconMenuItem  *item,
                                    gboolean        *affects_the_outside,
                                    GError         **error)
 {
-  XfceRc       *rc;
-  gboolean      boolean;
-  GList        *categories = NULL;
-  GList        *lp;
-  GList        *old_categories = NULL;
-  gchar       **mt;
-  gchar       **str_list;
-  const gchar  *string;
-  const gchar  *name;
-  const gchar  *exec;
-  gchar        *filename;
-  gchar        *url_exec = NULL;
+  XfceRc               *rc;
+  GarconMenuItemAction *action = NULL;
+  gboolean              boolean;
+  GList                *categories = NULL;
+  GList                *lp;
+  GList                *old_categories = NULL;
+  gchar               **mt;
+  gchar               **str_list;
+  const gchar          *string;
+  const gchar          *name;
+  const gchar          *exec;
+  gchar                *filename;
+  gchar                *action_group;
+  gchar                *url_exec = NULL;
 
   g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), FALSE);
   g_return_val_if_fail (G_IS_FILE (file), FALSE);
@@ -994,6 +1080,79 @@ garcon_menu_item_reload_from_file (GarconMenuItem  *item,
   item->priv->only_show_in = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, ";");
   item->priv->not_show_in = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, ";");
 
+  /* Update application actions */
+  g_hash_table_remove_all (item->priv->actions);
+  str_list = xfce_rc_read_list_entry (rc, G_KEY_FILE_DESKTOP_KEY_ACTIONS, ";");
+  if (G_LIKELY (str_list != NULL))
+    {
+      for (mt = str_list; *mt != NULL; ++mt)
+        {
+          if (**mt != '\0')
+            {
+              /* Set current desktop action group */
+              action_group = g_strdup_printf ("Desktop Action %s", *mt);
+              xfce_rc_set_group (rc, action_group);
+
+              /* Parse name and exec command */
+              name = xfce_rc_read_entry (rc, G_KEY_FILE_DESKTOP_KEY_NAME, NULL);
+              exec = xfce_rc_read_entry_untranslated (rc, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
+
+              /* Validate Name and Exec fields */
+              if (G_LIKELY (exec != NULL && name != NULL))
+                {
+                  /* Allocate a new action instance */
+                  action = g_object_new (GARCON_TYPE_MENU_ITEM_ACTION,
+                                         "name", name,
+                                         "command", exec,
+                                         NULL);
+
+                  garcon_menu_item_set_action (item, *mt, action);
+                }
+              g_free (action_group);
+            }
+          else
+            g_free (*mt);
+        }
+
+      /* Cleanup */
+      g_free (str_list);
+    }
+
+  else
+    {
+      str_list = xfce_rc_read_list_entry (rc, "X-Ayatana-Desktop-Shortcuts", ";");
+      if (G_LIKELY (str_list != NULL))
+        {
+          for (mt = str_list; *mt != NULL; ++mt)
+            {
+              if (**mt != '\0')
+                {
+                  action_group = g_strdup_printf ("%s Shortcut Group", *mt);
+                  xfce_rc_set_group (rc, action_group);
+
+                  name = xfce_rc_read_entry (rc, G_KEY_FILE_DESKTOP_KEY_NAME, NULL);
+                  exec = xfce_rc_read_entry_untranslated (rc, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
+
+                  if (G_LIKELY (exec != NULL && name != NULL))
+                    {
+                      action = g_object_new (GARCON_TYPE_MENU_ITEM_ACTION,
+                                             "name", name,
+                                             "command", exec,
+                                             NULL);
+
+                      garcon_menu_item_set_action (item, *mt, action);
+                    }
+
+                  g_free (action_group);
+                }
+              else
+                g_free (*mt);
+            }
+
+          g_free (str_list);
+        }
+    }
+
   /* Flush property notifications */
   g_object_thaw_notify (G_OBJECT (item));
 
@@ -1429,6 +1588,56 @@ garcon_menu_item_has_category (GarconMenuItem *item,
 
 
 
+GList *
+garcon_menu_item_get_actions (GarconMenuItem *item)
+{
+  g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), NULL);
+  
+  return g_hash_table_get_keys (item->priv->actions);
+}
+
+
+
+GarconMenuItemAction *
+garcon_menu_item_get_action (GarconMenuItem *item,
+                             const gchar    *action_name)
+{
+  g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), NULL);
+  
+  return g_hash_table_lookup (item->priv->actions, action_name);
+}
+
+
+
+
+void
+garcon_menu_item_set_action (GarconMenuItem       *item,
+                             const gchar          *action_name,
+                             GarconMenuItemAction *action)
+{
+  g_return_if_fail (GARCON_IS_MENU_ITEM (item));
+  g_return_if_fail (GARCON_IS_MENU_ITEM_ACTION (action));
+  
+  /* Insert into the hash table and remove old action (if any) */
+  g_hash_table_replace (item->priv->actions, g_strdup (action_name), action);
+
+  /* Grab a reference on the action */
+  garcon_menu_item_action_ref (action);
+}
+
+
+
+gboolean
+garcon_menu_item_has_action (GarconMenuItem  *item,
+                             const gchar     *action_name)
+{
+  g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), FALSE);
+
+  return g_hash_table_contains (item->priv->actions, action_name);
+}
+
+
+
 gboolean
 garcon_menu_item_get_show_in_environment (GarconMenuItem *item)
 {
diff --git a/garcon/garcon-menu-item.h b/garcon/garcon-menu-item.h
index ef17732..9b6b7b3 100644
--- a/garcon/garcon-menu-item.h
+++ b/garcon/garcon-menu-item.h
@@ -2,6 +2,7 @@
 /*-
  * Copyright (c) 2006-2010 Jannis Pohlmann <jannis at xfce.org>
  * Copyright (c) 2009      Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2015      Danila Poyarkov <dannotemail at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,6 +29,7 @@
 
 #include <glib-object.h>
 #include <gio/gio.h>
+#include <garcon/garcon-menu-item-action.h>
 
 G_BEGIN_DECLS
 
@@ -60,74 +62,82 @@ struct _GarconMenuItem
 
 
 
-GType           garcon_menu_item_get_type                          (void) G_GNUC_CONST;
+GType                 garcon_menu_item_get_type                          (void) G_GNUC_CONST;
 
-GarconMenuItem *garcon_menu_item_new                               (GFile           *file) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-GarconMenuItem *garcon_menu_item_new_for_path                      (const gchar     *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-GarconMenuItem *garcon_menu_item_new_for_uri                       (const gchar     *uri) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+GarconMenuItem       *garcon_menu_item_new                               (GFile           *file) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+GarconMenuItem       *garcon_menu_item_new_for_path                      (const gchar     *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+GarconMenuItem       *garcon_menu_item_new_for_uri                       (const gchar     *uri) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
-gboolean        garcon_menu_item_reload                            (GarconMenuItem  *item,
+gboolean              garcon_menu_item_reload                            (GarconMenuItem  *item,
                                                                     gboolean        *affects_the_outside,
                                                                     GError         **error);
 
-gboolean        garcon_menu_item_reload_from_file                  (GarconMenuItem  *item,
+gboolean              garcon_menu_item_reload_from_file                  (GarconMenuItem  *item,
                                                                     GFile           *file,
                                                                     gboolean        *affects_the_outside,
                                                                     GError         **error);
 
-GFile          *garcon_menu_item_get_file                          (GarconMenuItem  *item);
-
-gchar          *garcon_menu_item_get_uri                           (GarconMenuItem  *item) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-const gchar    *garcon_menu_item_get_desktop_id                    (GarconMenuItem  *item);
-void            garcon_menu_item_set_desktop_id                    (GarconMenuItem  *item,
-                                                                    const gchar     *desktop_id);
-
-const gchar    *garcon_menu_item_get_command                       (GarconMenuItem  *item);
-void            garcon_menu_item_set_command                       (GarconMenuItem  *item,
-                                                                    const gchar     *command);
-const gchar    *garcon_menu_item_get_try_exec                      (GarconMenuItem  *item);
-void            garcon_menu_item_set_try_exec                      (GarconMenuItem  *item,
-                                                                    const gchar     *try_exec);
-const gchar    *garcon_menu_item_get_name                          (GarconMenuItem  *item);
-void            garcon_menu_item_set_name                          (GarconMenuItem  *item,
-                                                                    const gchar     *name);
-const gchar    *garcon_menu_item_get_generic_name                  (GarconMenuItem  *item);
-void            garcon_menu_item_set_generic_name                  (GarconMenuItem  *item,
-                                                                    const gchar     *generic_name);
-const gchar    *garcon_menu_item_get_comment                       (GarconMenuItem  *item);
-void            garcon_menu_item_set_comment                       (GarconMenuItem  *item,
-                                                                    const gchar     *comment);
-const gchar    *garcon_menu_item_get_icon_name                     (GarconMenuItem  *item);
-void            garcon_menu_item_set_icon_name                     (GarconMenuItem  *item,
-                                                                    const gchar     *icon_name);
-const gchar    *garcon_menu_item_get_path                          (GarconMenuItem  *item);
-void            garcon_menu_item_set_path                          (GarconMenuItem  *item,
-                                                                    const gchar     *path);
-gboolean        garcon_menu_item_get_hidden                        (GarconMenuItem  *item);
-void            garcon_menu_item_set_hidden                        (GarconMenuItem  *item,
-                                                                    gboolean         hidden);
-gboolean        garcon_menu_item_requires_terminal                 (GarconMenuItem  *item);
-void            garcon_menu_item_set_requires_terminal             (GarconMenuItem  *item,
-                                                                    gboolean         requires_terminal);
-gboolean        garcon_menu_item_get_no_display                    (GarconMenuItem  *item);
-void            garcon_menu_item_set_no_display                    (GarconMenuItem  *item,
-                                                                    gboolean         no_display);
-gboolean        garcon_menu_item_supports_startup_notification     (GarconMenuItem  *item);
-void            garcon_menu_item_set_supports_startup_notification (GarconMenuItem  *item,
-                                                                    gboolean         supports_startup_notification);
-GList          *garcon_menu_item_get_categories                    (GarconMenuItem  *item);
-void            garcon_menu_item_set_categories                    (GarconMenuItem  *item,
-                                                                    GList           *categories);
-gboolean        garcon_menu_item_has_category                      (GarconMenuItem  *item,
-                                                                    const gchar     *category);
-gboolean        garcon_menu_item_get_show_in_environment           (GarconMenuItem  *item);
-gboolean        garcon_menu_item_only_show_in_environment          (GarconMenuItem  *item);
-void            garcon_menu_item_ref                               (GarconMenuItem  *item);
-void            garcon_menu_item_unref                             (GarconMenuItem  *item);
-gint            garcon_menu_item_get_allocated                     (GarconMenuItem  *item);
-void            garcon_menu_item_increment_allocated               (GarconMenuItem  *item);
-void            garcon_menu_item_decrement_allocated               (GarconMenuItem  *item);
+GFile                *garcon_menu_item_get_file                          (GarconMenuItem  *item);
+
+gchar                *garcon_menu_item_get_uri                           (GarconMenuItem  *item) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+const gchar          *garcon_menu_item_get_desktop_id                    (GarconMenuItem  *item);
+void                  garcon_menu_item_set_desktop_id                    (GarconMenuItem  *item,
+                                                                          const gchar     *desktop_id);
+
+const gchar          *garcon_menu_item_get_command                       (GarconMenuItem  *item);
+void                  garcon_menu_item_set_command                       (GarconMenuItem  *item,
+                                                                          const gchar     *command);
+const gchar          *garcon_menu_item_get_try_exec                      (GarconMenuItem  *item);
+void                  garcon_menu_item_set_try_exec                      (GarconMenuItem  *item,
+                                                                          const gchar     *try_exec);
+const gchar          *garcon_menu_item_get_name                          (GarconMenuItem  *item);
+void                  garcon_menu_item_set_name                          (GarconMenuItem  *item,
+                                                                          const gchar     *name);
+const gchar          *garcon_menu_item_get_generic_name                  (GarconMenuItem  *item);
+void                  garcon_menu_item_set_generic_name                  (GarconMenuItem  *item,
+                                                                          const gchar     *generic_name);
+const gchar          *garcon_menu_item_get_comment                       (GarconMenuItem  *item);
+void                  garcon_menu_item_set_comment                       (GarconMenuItem  *item,
+                                                                          const gchar     *comment);
+const gchar          *garcon_menu_item_get_icon_name                     (GarconMenuItem  *item);
+void                  garcon_menu_item_set_icon_name                     (GarconMenuItem  *item,
+                                                                          const gchar     *icon_name);
+const gchar          *garcon_menu_item_get_path                          (GarconMenuItem  *item);
+void                  garcon_menu_item_set_path                          (GarconMenuItem  *item,
+                                                                          const gchar     *path);
+gboolean              garcon_menu_item_get_hidden                        (GarconMenuItem  *item);
+void                  garcon_menu_item_set_hidden                        (GarconMenuItem  *item,
+                                                                          gboolean         hidden);
+gboolean              garcon_menu_item_requires_terminal                 (GarconMenuItem  *item);
+void                  garcon_menu_item_set_requires_terminal             (GarconMenuItem  *item,
+                                                                          gboolean         requires_terminal);
+gboolean              garcon_menu_item_get_no_display                    (GarconMenuItem  *item);
+void                  garcon_menu_item_set_no_display                    (GarconMenuItem  *item,
+                                                                          gboolean         no_display);
+gboolean              garcon_menu_item_supports_startup_notification     (GarconMenuItem  *item);
+void                  garcon_menu_item_set_supports_startup_notification (GarconMenuItem  *item,
+                                                                          gboolean         supports_startup_notification);
+GList                *garcon_menu_item_get_categories                    (GarconMenuItem  *item);
+void                  garcon_menu_item_set_categories                    (GarconMenuItem  *item,
+                                                                          GList           *categories);
+gboolean              garcon_menu_item_has_category                      (GarconMenuItem  *item,
+                                                                          const gchar     *category);
+GList                *garcon_menu_item_get_actions                       (GarconMenuItem  *item);
+GarconMenuItemAction *garcon_menu_item_get_action                        (GarconMenuItem  *item,
+                                                                          const gchar     *action_name);
+void                  garcon_menu_item_set_action                        (GarconMenuItem       *item,
+                                                                          const gchar          *action_name,
+                                                                          GarconMenuItemAction *action);
+gboolean              garcon_menu_item_has_action                        (GarconMenuItem  *item,
+                                                                          const gchar     *action_name);
+gboolean              garcon_menu_item_get_show_in_environment           (GarconMenuItem  *item);
+gboolean              garcon_menu_item_only_show_in_environment          (GarconMenuItem  *item);
+void                  garcon_menu_item_ref                               (GarconMenuItem  *item);
+void                  garcon_menu_item_unref                             (GarconMenuItem  *item);
+gint                  garcon_menu_item_get_allocated                     (GarconMenuItem  *item);
+void                  garcon_menu_item_increment_allocated               (GarconMenuItem  *item);
+void                  garcon_menu_item_decrement_allocated               (GarconMenuItem  *item);
 
 G_END_DECLS
 
diff --git a/garcon/garcon.h b/garcon/garcon.h
index 0a47778..098e694 100644
--- a/garcon/garcon.h
+++ b/garcon/garcon.h
@@ -31,6 +31,7 @@
 #include <garcon/garcon-environment.h>
 #include <garcon/garcon-menu.h>
 #include <garcon/garcon-menu-item.h>
+#include <garcon/garcon-menu-item-action.h>
 #include <garcon/garcon-menu-item-cache.h>
 #include <garcon/garcon-menu-item-pool.h>
 #include <garcon/garcon-menu-node.h>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list