]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkaccellabel.c
Fix some warnings.
[~andy/gtk] / gtk / gtkaccellabel.c
index 4734146442279c7c0ad87a17052d981dbf7dc566..745ceca639d45c288d9a2b0da7382b06472a4f08 100644 (file)
  * files for a list of changes.  These files are distributed with
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
-
-#include <string.h>
-#include <ctype.h>
+#include "gtkaccellabel.h"
+#include "gtkaccelmap.h"
 #include "gtkmain.h"
 #include "gtksignal.h"
-#include "gtkaccellabel.h"
 #include "gtkintl.h"
 
+#include <string.h>
+#include <ctype.h>
+
 enum {
   PROP_0,
+  PROP_ACCEL_CLOSURE,
   PROP_ACCEL_WIDGET
 };
 
@@ -90,45 +92,44 @@ static void
 gtk_accel_label_class_init (GtkAccelLabelClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-  GtkObjectClass *object_class;
-  GtkWidgetClass *widget_class;
-  GtkMiscClass *misc_class;
-  GtkLabelClass *label_class;
+  GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
   
   accel_label_class = class;
-  object_class = (GtkObjectClass*) class;
-  widget_class = (GtkWidgetClass*) class;
-  misc_class = (GtkMiscClass*) class;
-  label_class = (GtkLabelClass*) class;
-  
-  parent_class = gtk_type_class (GTK_TYPE_LABEL);
+  parent_class = g_type_class_peek_parent (class);
   
   gobject_class->finalize = gtk_accel_label_finalize;
   gobject_class->set_property = gtk_accel_label_set_property;
   gobject_class->get_property = gtk_accel_label_get_property;
   
   object_class->destroy = gtk_accel_label_destroy;
-  
-  g_object_class_install_property (G_OBJECT_CLASS(object_class),
-                                   PROP_ACCEL_WIDGET,
-                                   g_param_spec_object ("accel_widget",
-                                                        _("Accelerator widget"),
-                                                        _("The widget monitored by this accelerator label"),
-                                                        GTK_TYPE_WIDGET,
-                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
-
    
   widget_class->size_request = gtk_accel_label_size_request;
   widget_class->expose_event = gtk_accel_label_expose_event;
 
   class->signal_quote1 = g_strdup ("<:");
   class->signal_quote2 = g_strdup (":>");
-  class->mod_name_shift = g_strdup ("Shft");
-  class->mod_name_control = g_strdup ("Ctl");
+  class->mod_name_shift = g_strdup ("Shift");
+  class->mod_name_control = g_strdup ("Ctrl");
   class->mod_name_alt = g_strdup ("Alt");
   class->mod_separator = g_strdup ("+");
   class->accel_seperator = g_strdup (" / ");
   class->latin1_to_char = TRUE;
+  
+  g_object_class_install_property (G_OBJECT_CLASS (object_class),
+                                   PROP_ACCEL_CLOSURE,
+                                   g_param_spec_boxed ("accel_closure",
+                                                      _("Accelerator Closure"),
+                                                      _("The closure to be monitored for accelerator changes"),
+                                                      G_TYPE_CLOSURE,
+                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
+  g_object_class_install_property (G_OBJECT_CLASS (object_class),
+                                   PROP_ACCEL_WIDGET,
+                                   g_param_spec_object ("accel_widget",
+                                                        _("Accelerator Widget"),
+                                                        _("The widget to be monitored for accelerator changes"),
+                                                        GTK_TYPE_WIDGET,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 static void
@@ -143,8 +144,11 @@ gtk_accel_label_set_property (GObject      *object,
 
   switch (prop_id)
     {
+    case PROP_ACCEL_CLOSURE:
+      gtk_accel_label_set_accel_closure (accel_label, g_value_get_boxed (value));
+      break;
     case PROP_ACCEL_WIDGET:
-      gtk_accel_label_set_accel_widget (accel_label, (GtkWidget*) g_value_get_object (value));
+      gtk_accel_label_set_accel_widget (accel_label, g_value_get_object (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -152,10 +156,11 @@ gtk_accel_label_set_property (GObject      *object,
     }
 }
 
-static void gtk_accel_label_get_property (GObject    *object,
-                                         guint       prop_id,
-                                         GValue     *value,
-                                         GParamSpec *pspec)
+static void
+gtk_accel_label_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
 {
   GtkAccelLabel  *accel_label;
 
@@ -163,8 +168,11 @@ static void gtk_accel_label_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_ACCEL_CLOSURE:
+      g_value_set_boxed (value, accel_label->accel_closure);
+      break;
     case PROP_ACCEL_WIDGET:
-       g_value_set_object (value, G_OBJECT (accel_label->accel_widget));
+      g_value_set_object (value, accel_label->accel_widget);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -178,6 +186,8 @@ gtk_accel_label_init (GtkAccelLabel *accel_label)
   accel_label->queue_id = 0;
   accel_label->accel_padding = 3;
   accel_label->accel_widget = NULL;
+  accel_label->accel_closure = NULL;
+  accel_label->accel_group = NULL;
   accel_label->accel_string = NULL;
   
   gtk_accel_label_refetch (accel_label);
@@ -207,6 +217,7 @@ gtk_accel_label_destroy (GtkObject *object)
   accel_label = GTK_ACCEL_LABEL (object);
 
   gtk_accel_label_set_accel_widget (accel_label, NULL);
+  gtk_accel_label_set_accel_closure (accel_label, NULL);
   
   GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }
@@ -214,12 +225,13 @@ gtk_accel_label_destroy (GtkObject *object)
 static void
 gtk_accel_label_finalize (GObject *object)
 {
-  GtkAccelLabel *accel_label;
-  
-  g_return_if_fail (GTK_IS_ACCEL_LABEL (object));
-  
-  accel_label = GTK_ACCEL_LABEL (object);
-  
+  GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (object);
+
+  if (accel_label->queue_id)
+    {
+      gtk_idle_remove (accel_label->queue_id);
+      accel_label->queue_id = 0;
+    }
   g_free (accel_label->accel_string);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -232,10 +244,10 @@ gtk_accel_label_finalize (GObject *object)
  * Fetches the widget monitored by this accelerator label. See
  * gtk_accel_label_set_accel_widget().
  *
- * Return value: the widget monitored by the accelerator label,
+ * Return value: the object monitored by the accelerator label,
  *               or %NULL.
  **/
-GtkWidget *
+GtkWidget*
 gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label)
 {
   g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), NULL);
@@ -333,56 +345,118 @@ gtk_accel_label_expose_event (GtkWidget      *widget,
        }
     }
   
-  return TRUE;
+  return FALSE;
 }
 
 static void
-gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label)
+refetch_widget_accel_closure (GtkAccelLabel *accel_label)
 {
+  GClosure *closure = NULL;
+  GList *clist, *list;
+  
   g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
-
-  if (accel_label->queue_id == 0)
-    accel_label->queue_id = gtk_idle_add_priority (G_PRIORITY_HIGH_IDLE,
-                                                  (GtkFunction) gtk_accel_label_refetch_idle,
-                                                  accel_label);
+  g_return_if_fail (GTK_IS_WIDGET (accel_label->accel_widget));
+  
+  clist = gtk_widget_list_accel_closures (accel_label->accel_widget);
+  for (list = clist; list; list = list->next)
+    {
+      /* we just take the first closure used */
+      closure = list->data;
+      break;
+    }
+  g_list_free (clist);
+  gtk_accel_label_set_accel_closure (accel_label, closure);
 }
 
+/**
+ * gtk_accel_label_set_accel_widget:
+ * @accel_label: a #GtkAccelLabel
+ * @accel_widget: the widget to be monitored.
+ *
+ * Sets the widget to be monitored by this accelerator label. 
+ **/
 void
 gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
-                                 GtkWidget     *accel_widget)
+                                 GtkWidget     *accel_widget)
 {
   g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
-  if (accel_widget != NULL)
+  if (accel_widget)
     g_return_if_fail (GTK_IS_WIDGET (accel_widget));
-  
+    
   if (accel_widget != accel_label->accel_widget)
     {
       if (accel_label->accel_widget)
        {
-         gtk_signal_disconnect_by_func (GTK_OBJECT (accel_label->accel_widget),
-                                        GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch),
-                                        accel_label);
-         gtk_widget_unref (accel_label->accel_widget);
-       }
-      if (accel_label->queue_id)
-       {
-         gtk_idle_remove (accel_label->queue_id);
-         accel_label->queue_id = 0;
+         gtk_accel_label_set_accel_closure (accel_label, NULL);
+         g_signal_handlers_disconnect_by_func (accel_label->accel_widget,
+                                               G_CALLBACK (refetch_widget_accel_closure),
+                                               accel_label);
+         g_object_unref (accel_label->accel_widget);
        }
       accel_label->accel_widget = accel_widget;
       if (accel_label->accel_widget)
        {
-         gtk_widget_ref (accel_label->accel_widget);
-         gtk_signal_connect_object_after (GTK_OBJECT (accel_label->accel_widget),
-                                          "add-accelerator",
-                                          GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch),
-                                          GTK_OBJECT (accel_label));
-         gtk_signal_connect_object_after (GTK_OBJECT (accel_label->accel_widget),
-                                          "remove-accelerator",
-                                          GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch),
-                                          GTK_OBJECT (accel_label));
+         g_object_ref (accel_label->accel_widget);
+         g_signal_connect_object (accel_label->accel_widget, "accel_closures_changed",
+                                  G_CALLBACK (refetch_widget_accel_closure),
+                                  accel_label, G_CONNECT_SWAPPED);
+         refetch_widget_accel_closure (accel_label);
        }
-       g_object_notify (G_OBJECT (accel_label), "accel_widget");
+      g_object_notify (G_OBJECT (accel_label), "accel_widget");
+    }
+}
+
+static void
+gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label)
+{
+  g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
+
+  if (accel_label->queue_id == 0)
+    accel_label->queue_id = gtk_idle_add_priority (G_PRIORITY_HIGH_IDLE,
+                                                  (GtkFunction) gtk_accel_label_refetch_idle,
+                                                  accel_label);
+}
+
+static void
+check_accel_changed (GtkAccelGroup  *accel_group,
+                    guint           keyval,
+                    GdkModifierType modifier,
+                    GClosure       *accel_closure,
+                    GtkAccelLabel  *accel_label)
+{
+  if (accel_closure == accel_label->accel_closure)
+    gtk_accel_label_queue_refetch (accel_label);
+}
+
+void
+gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
+                                  GClosure      *accel_closure)
+{
+  g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
+  if (accel_closure)
+    g_return_if_fail (gtk_accel_group_from_accel_closure (accel_closure) != NULL);
+
+  if (accel_closure != accel_label->accel_closure)
+    {
+      if (accel_label->accel_closure)
+       {
+         g_signal_handlers_disconnect_by_func (accel_label->accel_group,
+                                               G_CALLBACK (check_accel_changed),
+                                               accel_label);
+         accel_label->accel_group = NULL;
+         g_closure_unref (accel_label->accel_closure);
+       }
+      accel_label->accel_closure = accel_closure;
+      if (accel_label->accel_closure)
+       {
+         g_closure_ref (accel_label->accel_closure);
+         accel_label->accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+         g_signal_connect_object (accel_label->accel_group, "accel_changed",
+                                  G_CALLBACK (check_accel_changed),
+                                  accel_label, 0);
+       }
+      gtk_accel_label_queue_refetch (accel_label);
+      g_object_notify (G_OBJECT (accel_label), "accel_closure");
     }
 }
 
@@ -398,6 +472,14 @@ gtk_accel_label_refetch_idle (GtkAccelLabel *accel_label)
   return retval;
 }
 
+static gboolean
+find_accel (GtkAccelKey *key,
+           GClosure    *closure,
+           gpointer     data)
+{
+  return data == (gpointer) closure;
+}
+
 gboolean
 gtk_accel_label_refetch (GtkAccelLabel *accel_label)
 {
@@ -406,96 +488,79 @@ gtk_accel_label_refetch (GtkAccelLabel *accel_label)
   g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE);
 
   class = GTK_ACCEL_LABEL_GET_CLASS (accel_label);
-  
+
   g_free (accel_label->accel_string);
   accel_label->accel_string = NULL;
-  
-  if (accel_label->accel_widget)
+
+  if (accel_label->accel_closure)
     {
-      GtkAccelEntry *entry = NULL;
-      GSList *slist;
-      
-      slist = gtk_accel_group_entries_from_object (GTK_OBJECT (accel_label->accel_widget));
-      for (; slist; slist = slist->next)
+      GtkAccelKey *key = gtk_accel_group_find (accel_label->accel_group, find_accel, accel_label->accel_closure);
+
+      if (key && key->accel_flags & GTK_ACCEL_VISIBLE)
        {
-         entry = slist->data;
-         if (entry->accel_flags & GTK_ACCEL_VISIBLE)
+         GString *gstring;
+         gboolean seen_mod = FALSE;
+         
+         gstring = g_string_new (accel_label->accel_string);
+         g_string_append (gstring, gstring->len ? class->accel_seperator : "   ");
+         
+         if (key->accel_mods & GDK_SHIFT_MASK)
            {
-             GString *gstring;
-             gboolean had_mod;
-             
-             gstring = g_string_new (accel_label->accel_string);
-             if (gstring->len)
-               g_string_append (gstring, class->accel_seperator);
-             else
-               g_string_append (gstring, "   ");
-
-             if (entry->accel_flags & GTK_ACCEL_SIGNAL_VISIBLE)
-               {
-                 g_string_append (gstring, class->signal_quote1);
-                 g_string_append (gstring, gtk_signal_name (entry->signal_id));
-                 g_string_append (gstring, class->signal_quote2);
-               }
-             
-             had_mod = FALSE;
-             if (entry->accelerator_mods & GDK_SHIFT_MASK)
-               {
-                 g_string_append (gstring, class->mod_name_shift);
-                 had_mod = TRUE;
-               }
-             if (entry->accelerator_mods & GDK_CONTROL_MASK)
-               {
-                 if (had_mod)
-                   g_string_append (gstring, class->mod_separator);
-                 g_string_append (gstring, class->mod_name_control);
-                 had_mod = TRUE;
-               }
-             if (entry->accelerator_mods & GDK_MOD1_MASK)
-               {
-                 if (had_mod)
-                   g_string_append (gstring, class->mod_separator);
-                 g_string_append (gstring, class->mod_name_alt);
-                 had_mod = TRUE;
-               }
-             
-             if (had_mod)
+             g_string_append (gstring, class->mod_name_shift);
+             seen_mod = TRUE;
+           }
+         if (key->accel_mods & GDK_CONTROL_MASK)
+           {
+             if (seen_mod)
                g_string_append (gstring, class->mod_separator);
-             if (entry->accelerator_key < 0x80 ||
-                 (entry->accelerator_key > 0x80 &&
-                  entry->accelerator_key <= 0xff &&
-                  class->latin1_to_char))
-               {
-                 switch (entry->accelerator_key)
-                   {
-                   case ' ':
-                     g_string_append (gstring, "Space");
-                     break;
-                   case '\\':
-                     g_string_append (gstring, "Backslash");
-                     break;
-                   default:
-                     g_string_append_c (gstring, toupper (entry->accelerator_key));
-                     break;
-                   }
-               }
-             else
+             g_string_append (gstring, class->mod_name_control);
+             seen_mod = TRUE;
+           }
+         if (key->accel_mods & GDK_MOD1_MASK)
+           {
+             if (seen_mod)
+               g_string_append (gstring, class->mod_separator);
+             g_string_append (gstring, class->mod_name_alt);
+             seen_mod = TRUE;
+           }
+         if (seen_mod)
+           g_string_append (gstring, class->mod_separator);
+         if (key->accel_key < 0x80 ||
+             (key->accel_key > 0x80 &&
+              key->accel_key <= 0xff &&
+              class->latin1_to_char))
+           {
+             switch (key->accel_key)
                {
-                 gchar *tmp;
-                 
-                 tmp = gtk_accelerator_name (entry->accelerator_key, 0);
-                 if (tmp[0] != 0 && tmp[1] == 0)
-                   tmp[0] = toupper (tmp[0]);
-                 g_string_append (gstring, tmp);
-                 g_free (tmp);
+               case ' ':
+                 g_string_append (gstring, "Space");
+                 break;
+               case '\\':
+                 g_string_append (gstring, "Backslash");
+                 break;
+               default:
+                 g_string_append_unichar (gstring, toupper (key->accel_key));
+                 break;
                }
-
-             g_free (accel_label->accel_string);
-             accel_label->accel_string = gstring->str;
-             g_string_free (gstring, FALSE);
            }
+         else
+           {
+             gchar *tmp;
+             
+             tmp = gtk_accelerator_name (key->accel_key, 0);
+             if (tmp[0] != 0 && tmp[1] == 0)
+               tmp[0] = toupper (tmp[0]);
+             g_string_append (gstring, tmp);
+             g_free (tmp);
+           }
+         g_free (accel_label->accel_string);
+         accel_label->accel_string = gstring->str;
+         g_string_free (gstring, FALSE);
        }
+      if (!accel_label->accel_string)
+       accel_label->accel_string = g_strdup ("-/-");
     }
-
+  
   if (!accel_label->accel_string)
     accel_label->accel_string = g_strdup ("");