[gtk/shortcuts-rebased-again: 73/91] shortcutaction: Integrate with GtkBuilder property parsing



commit a47d2915e0d29b945ca7a089bef975ae05a47bc4
Author: Benjamin Otte <otte redhat com>
Date:   Fri Aug 24 06:58:44 2018 +0200

    shortcutaction: Integrate with GtkBuilder property parsing
    
    <property name="action">action(win.quit)</property> style action
    specifications now work for GtkShortcutAction properties.

 gtk/gtkbuilder.c               |   8 +++
 gtk/gtkshortcutaction.c        | 109 ++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkshortcutactionprivate.h |  29 +++++++++++
 3 files changed, 145 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 2b0f6b7059..b802f57bed 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -213,6 +213,7 @@
 #include "gtkicontheme.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
+#include "gtkshortcutactionprivate.h"
 #include "gtkshortcuttrigger.h"
 #include "gtktestutils.h"
 #include "gtktypebuiltins.h"
@@ -2110,6 +2111,13 @@ gtk_builder_value_from_string_type (GtkBuilder   *builder,
               ret = FALSE;
             }
         }
+      else if (G_VALUE_HOLDS (value, GTK_TYPE_SHORTCUT_ACTION))
+        {
+          GtkShortcutAction *action = gtk_shortcut_action_parse_builder (builder, string, error);
+
+          /* Works for success and failure (NULL) case */
+          g_value_take_boxed (value, action);
+        }
       else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
         {
           gchar **vector = g_strsplit (string, "\n", 0);
diff --git a/gtk/gtkshortcutaction.c b/gtk/gtkshortcutaction.c
index 137e0b3d3b..bd2e8417f2 100644
--- a/gtk/gtkshortcutaction.c
+++ b/gtk/gtkshortcutaction.c
@@ -37,8 +37,9 @@
 
 #include "config.h"
 
-#include "gtkshortcutaction.h"
+#include "gtkshortcutactionprivate.h"
 
+#include "gtkbuilder.h"
 #include "gtkwidgetprivate.h"
 
 typedef struct _GtkShortcutActionClass GtkShortcutActionClass;
@@ -227,6 +228,112 @@ gtk_shortcut_action_activate (GtkShortcutAction      *self,
   return self->action_class->activate (self, flags, widget, args);
 }
 
+static char *
+string_is_function (const char *string,
+                    const char *function_name)
+{
+  gsize len;
+
+  if (!g_str_has_prefix (string, function_name))
+    return NULL;
+  string += strlen (function_name);
+
+  if (string[0] != '(')
+    return NULL;
+  string ++;
+
+  len = strlen (string);
+  if (len == 0 || string[len - 1] != ')')
+    return NULL;
+
+  return g_strndup (string, len - 1);
+}
+
+GtkShortcutAction *
+gtk_shortcut_action_parse_builder (GtkBuilder  *builder,
+                                   const char  *string,
+                                   GError     **error)
+{
+  GtkShortcutAction *result;
+  char *arg;
+
+  if (g_str_equal (string, "nothing"))
+    return gtk_nothing_action_new ();
+  if (g_str_equal (string, "activate"))
+    return gtk_activate_action_new ();
+  if (g_str_equal (string, "mnemonic-activate"))
+    return gtk_mnemonic_action_new ();
+
+  if ((arg = string_is_function (string, "action")))
+    {
+      result = gtk_action_action_new (arg);
+      g_free (arg);
+    }
+  else if ((arg = string_is_function (string, "signal")))
+    {
+      result = gtk_signal_action_new (arg);
+      g_free (arg);
+    }
+  else if ((arg = string_is_function (string, "callback")))
+    {
+      GtkShortcutFunc callback;
+
+      callback = (GtkShortcutFunc) gtk_builder_lookup_callback_symbol (builder, arg);
+      if (!callback)
+        {
+          static GModule *module = NULL;
+
+          if (G_UNLIKELY (module == NULL))
+            module = g_module_open (NULL, 0);
+
+          if (!g_module_symbol (module, arg, (gpointer) &callback))
+            {
+              g_set_error (error,
+                           GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE,
+                           "No function named \"%s\" found", arg);
+              g_free (arg);
+              return NULL;
+            }
+        }
+      
+      result = gtk_callback_action_new (callback, NULL, NULL);
+      g_free (arg);
+    }
+  else if ((arg = string_is_function (string, "gaction")))
+    {
+      GObject *object = gtk_builder_get_object (builder, arg);
+
+      if (object == NULL)
+        {
+          g_set_error (error,
+                       GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_ID,
+                       "Action with ID \"%s\" not found", arg);
+          g_free (arg);
+          return NULL;
+        }
+      else if (!G_IS_ACTION (object))
+        {
+          g_set_error (error,
+                       GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_ID,
+                       "Object with ID \"%s\" is not a GAction", arg);
+          g_free (arg);
+          return NULL;
+        }
+
+      result = gtk_gaction_action_new (G_ACTION (object));
+      g_free (arg);
+    }
+  else
+    {
+      g_set_error (error,
+                   GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE,
+                   "String \"%s\" does not specify a GtkShortcutAction", string);
+      return NULL;
+    }
+
+  return result;
+}
+
 /*** GTK_SHORTCUT_ACTION_NOTHING ***/
 
 typedef struct _GtkNothingAction GtkNothingAction;
diff --git a/gtk/gtkshortcutactionprivate.h b/gtk/gtkshortcutactionprivate.h
new file mode 100644
index 0000000000..4c5a0db3ef
--- /dev/null
+++ b/gtk/gtkshortcutactionprivate.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_SHORTCUT_ACTION_PRIVATE_H__
+#define __GTK_SHORTCUT_ACTION_PRIVATE_H__
+
+#include "gtkshortcutaction.h"
+
+GtkShortcutAction *     gtk_shortcut_action_parse_builder       (GtkBuilder              *builder,
+                                                                 const char              *string,
+                                                                 GError                 **error);
+
+#endif /* __GTK_SHORTCUT_ACTION_PRIVATE_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]