]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcellrendereraccel.c
Rename GdkQuartzWindow.h and .c to GdkQuartzNSWindow.h and .c
[~andy/gtk] / gtk / gtkcellrendereraccel.c
index 139f7701f98fc49143ed6ea51f41b04bd1e9929b..b0a42dbc36446b6fd9a30823444452c2474fa969 100644 (file)
  */
 
 #include "config.h"
+
+#include "gtkcellrendereraccel.h"
+
+#include "gdk/gdkkeysyms.h"
+
 #include "gtkintl.h"
 #include "gtkaccelgroup.h"
 #include "gtkmarshalers.h"
-#include "gtkcellrendereraccel.h"
 #include "gtklabel.h"
 #include "gtkeventbox.h"
+#include "gtkmain.h"
+#include "gtksizerequest.h"
 #include "gtkprivate.h"
-#include "gdk/gdkkeysyms.h"
-#include "gtkalias.h"
 
 
 static void gtk_cell_renderer_accel_get_property (GObject         *object,
@@ -37,21 +41,25 @@ static void gtk_cell_renderer_accel_set_property (GObject         *object,
                                                   guint            param_id,
                                                   const GValue    *value,
                                                   GParamSpec      *pspec);
-static void gtk_cell_renderer_accel_get_size     (GtkCellRenderer *cell,
-                                                  GtkWidget       *widget,
-                                                  GdkRectangle    *cell_area,
-                                                  gint            *x_offset,
-                                                  gint            *y_offset,
-                                                  gint            *width,
-                                                  gint            *height);
+static void gtk_cell_renderer_accel_get_size     (GtkCellRenderer    *cell,
+                                                  GtkWidget          *widget,
+                                                  const GdkRectangle *cell_area,
+                                                  gint               *x_offset,
+                                                  gint               *y_offset,
+                                                  gint               *width,
+                                                  gint               *height);
 static GtkCellEditable *
-           gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
-                                                  GdkEvent        *event,
-                                                  GtkWidget       *widget,
-                                                  const gchar     *path,
-                                                  GdkRectangle    *background_area,
-                                                  GdkRectangle    *cell_area,
-                                                  GtkCellRendererState flags);
+           gtk_cell_renderer_accel_start_editing (GtkCellRenderer      *cell,
+                                                  GdkEvent             *event,
+                                                  GtkWidget            *widget,
+                                                  const gchar          *path,
+                                                  const GdkRectangle   *background_area,
+                                                  const GdkRectangle   *cell_area,
+                                                  GtkCellRendererState  flags);
+static gchar *convert_keysym_state_to_string     (GtkCellRendererAccel *accel,
+                                                  guint                 keysym,
+                                                  GdkModifierType       mask,
+                                                  guint                 keycode);
 
 enum {
   ACCEL_EDITED,
@@ -67,6 +75,23 @@ enum {
   PROP_ACCEL_MODE
 };
 
+struct _GtkCellRendererAccelPrivate
+{
+  GtkCellRendererAccelMode accel_mode;
+
+  GtkWidget *edit_widget;
+  GtkWidget *grab_widget;
+  GtkWidget *sizing_label;
+
+  GdkDevice *grab_keyboard;
+  GdkDevice *grab_pointer;
+
+  GdkModifierType accel_mods;
+
+  guint accel_key;
+  guint keycode;
+};
+
 static guint signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (GtkCellRendererAccel, gtk_cell_renderer_accel, GTK_TYPE_CELL_RENDERER_TEXT)
@@ -74,6 +99,15 @@ G_DEFINE_TYPE (GtkCellRendererAccel, gtk_cell_renderer_accel, GTK_TYPE_CELL_REND
 static void
 gtk_cell_renderer_accel_init (GtkCellRendererAccel *cell_accel)
 {
+  gchar *text;
+
+  cell_accel->priv = G_TYPE_INSTANCE_GET_PRIVATE (cell_accel,
+                                                  GTK_TYPE_CELL_RENDERER_ACCEL,
+                                                  GtkCellRendererAccelPrivate);
+
+  text = convert_keysym_state_to_string (cell_accel, 0, 0, 0);
+  g_object_set (cell_accel, "text", text, NULL);
+  g_free (text);
 }
 
 static void
@@ -203,6 +237,8 @@ gtk_cell_renderer_accel_class_init (GtkCellRendererAccelClass *cell_accel_class)
                                         g_cclosure_marshal_VOID__STRING,
                                         G_TYPE_NONE, 1,
                                         G_TYPE_STRING);
+
+  g_type_class_add_private (cell_accel_class, sizeof (GtkCellRendererAccelPrivate));
 }
 
 
@@ -227,21 +263,34 @@ convert_keysym_state_to_string (GtkCellRendererAccel *accel,
                                 GdkModifierType       mask,
                                guint                 keycode)
 {
+  GtkCellRendererAccelPrivate *priv = accel->priv;
+
   if (keysym == 0 && keycode == 0)
     /* This label is displayed in a treeview cell displaying
-     * a disabled accelerator key combination. Only include
-     * the text after the | in the translation.
+     * a disabled accelerator key combination.
      */
-    return g_strdup (Q_("Accelerator|Disabled"));
+    return g_strdup (C_("Accelerator", "Disabled"));
   else 
     {
-      if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
-       return gtk_accelerator_get_label (keysym, mask);
+      if (priv->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
+        {
+          if (!gtk_accelerator_valid (keysym, mask))
+            /* This label is displayed in a treeview cell displaying
+             * an accelerator key combination that is not valid according
+             * to gtk_accelerator_valid().
+             */
+            return g_strdup (C_("Accelerator", "Invalid"));
+
+          return gtk_accelerator_get_label (keysym, mask);
+        }
       else 
        {
          gchar *name;
 
-         name = gtk_accelerator_name (keysym, mask);
+         name = gtk_accelerator_get_label (keysym, mask);
+         if (name == NULL)
+           name = gtk_accelerator_name (keysym, mask);
+
          if (keysym == 0)
            {
              gchar *tmp;
@@ -262,20 +311,24 @@ gtk_cell_renderer_accel_get_property  (GObject    *object,
                                        GValue     *value,
                                        GParamSpec *pspec)
 {
-  GtkCellRendererAccel *accel = GTK_CELL_RENDERER_ACCEL (object);
+  GtkCellRendererAccelPrivate *priv = GTK_CELL_RENDERER_ACCEL (object)->priv;
 
   switch (param_id)
     {
     case PROP_ACCEL_KEY:
-      g_value_set_uint (value, accel->accel_key);
+      g_value_set_uint (value, priv->accel_key);
       break;
 
     case PROP_ACCEL_MODS:
-      g_value_set_flags (value, accel->accel_mods);
+      g_value_set_flags (value, priv->accel_mods);
+      break;
+
+    case PROP_KEYCODE:
+      g_value_set_uint (value, priv->keycode);
       break;
 
     case PROP_ACCEL_MODE:
-      g_value_set_enum (value, accel->accel_mode);
+      g_value_set_enum (value, priv->accel_mode);
       break;
 
     default:
@@ -290,6 +343,7 @@ gtk_cell_renderer_accel_set_property  (GObject      *object,
                                        GParamSpec   *pspec)
 {
   GtkCellRendererAccel *accel = GTK_CELL_RENDERER_ACCEL (object);
+  GtkCellRendererAccelPrivate *priv = accel->priv;
   gboolean changed = FALSE;
 
   switch (param_id)
@@ -298,9 +352,9 @@ gtk_cell_renderer_accel_set_property  (GObject      *object,
       {
        guint accel_key = g_value_get_uint (value);
 
-       if (accel->accel_key != accel_key)
+       if (priv->accel_key != accel_key)
          {
-           accel->accel_key = accel_key;
+           priv->accel_key = accel_key;
            changed = TRUE;
          }
       }
@@ -310,9 +364,9 @@ gtk_cell_renderer_accel_set_property  (GObject      *object,
       {
        guint accel_mods = g_value_get_flags (value);
 
-       if (accel->accel_mods != accel_mods)
+       if (priv->accel_mods != accel_mods)
          {
-           accel->accel_mods = accel_mods;
+           priv->accel_mods = accel_mods;
            changed = TRUE;
          }
       }
@@ -321,16 +375,16 @@ gtk_cell_renderer_accel_set_property  (GObject      *object,
       {
        guint keycode = g_value_get_uint (value);
 
-       if (accel->keycode != keycode)
+       if (priv->keycode != keycode)
          {
-           accel->keycode = keycode;
+           priv->keycode = keycode;
            changed = TRUE;
          }
       }
       break;
 
     case PROP_ACCEL_MODE:
-      accel->accel_mode = g_value_get_enum (value);
+      priv->accel_mode = g_value_get_enum (value);
       break;
       
     default:
@@ -341,29 +395,29 @@ gtk_cell_renderer_accel_set_property  (GObject      *object,
     {
       gchar *text;
 
-      text = convert_keysym_state_to_string (accel, accel->accel_key, accel->accel_mods, accel->keycode);
+      text = convert_keysym_state_to_string (accel, priv->accel_key, priv->accel_mods, priv->keycode);
       g_object_set (accel, "text", text, NULL);
       g_free (text);
     }
 }
 
 static void
-gtk_cell_renderer_accel_get_size (GtkCellRenderer *cell,
-                                  GtkWidget       *widget,
-                                  GdkRectangle    *cell_area,
-                                  gint            *x_offset,
-                                  gint            *y_offset,
-                                  gint            *width,
-                                  gint            *height)
+gtk_cell_renderer_accel_get_size (GtkCellRenderer    *cell,
+                                  GtkWidget          *widget,
+                                  const GdkRectangle *cell_area,
+                                  gint               *x_offset,
+                                  gint               *y_offset,
+                                  gint               *width,
+                                  gint               *height)
 
 {
-  GtkCellRendererAccel *accel = (GtkCellRendererAccel *) cell;
+  GtkCellRendererAccelPrivate *priv = GTK_CELL_RENDERER_ACCEL (cell)->priv;
   GtkRequisition requisition;
 
-  if (accel->sizing_label == NULL)
-    accel->sizing_label = gtk_label_new (_("New accelerator..."));
+  if (priv->sizing_label == NULL)
+    priv->sizing_label = gtk_label_new (_("New accelerator..."));
 
-  gtk_widget_size_request (accel->sizing_label, &requisition);
+  gtk_widget_get_preferred_size (priv->sizing_label, &requisition, NULL);
 
   GTK_CELL_RENDERER_CLASS (gtk_cell_renderer_accel_parent_class)->get_size (cell, widget, cell_area,
                                                                             x_offset, y_offset, width, height);
@@ -380,6 +434,7 @@ grab_key_callback (GtkWidget            *widget,
                    GdkEventKey          *event,
                    GtkCellRendererAccel *accel)
 {
+  GtkCellRendererAccelPrivate *priv = accel->priv;
   GdkModifierType accel_mods = 0;
   guint accel_key;
   gchar *path;
@@ -403,14 +458,14 @@ grab_key_callback (GtkWidget            *widget,
                                       NULL, NULL, NULL, &consumed_modifiers);
 
   accel_key = gdk_keyval_to_lower (event->keyval);
-  if (accel_key == GDK_ISO_Left_Tab) 
-    accel_key = GDK_Tab;
+  if (accel_key == GDK_KEY_ISO_Left_Tab) 
+    accel_key = GDK_KEY_Tab;
 
   accel_mods = event->state & gtk_accelerator_get_default_mod_mask ();
 
   /* Filter consumed modifiers 
    */
-  if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
+  if (priv->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
     accel_mods &= ~consumed_modifiers;
   
   /* Put shift back if it changed the case of the key, not otherwise.
@@ -422,9 +477,9 @@ grab_key_callback (GtkWidget            *widget,
     {
       switch (event->keyval)
        {
-       case GDK_Escape:
+       case GDK_KEY_Escape:
          goto out; /* cancel */
-       case GDK_BackSpace:
+       case GDK_KEY_BackSpace:
          /* clear the accelerator on Backspace */
          cleared = TRUE;
          goto out;
@@ -433,7 +488,7 @@ grab_key_callback (GtkWidget            *widget,
        }
     }
 
-  if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
+  if (priv->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
     {
       if (!gtk_accelerator_valid (accel_key, accel_mods))
        {
@@ -446,16 +501,19 @@ grab_key_callback (GtkWidget            *widget,
   edited = TRUE;
 
  out:
-  gdk_display_keyboard_ungrab (display, event->time);
-  gdk_display_pointer_ungrab (display, event->time);
+  gtk_device_grab_remove (priv->grab_widget, priv->grab_pointer);
+  gdk_device_ungrab (priv->grab_keyboard, event->time);
+  gdk_device_ungrab (priv->grab_pointer, event->time);
 
-  path = g_strdup (g_object_get_data (G_OBJECT (accel->edit_widget), "gtk-cell-renderer-text"));
+  path = g_strdup (g_object_get_data (G_OBJECT (priv->edit_widget), "gtk-cell-renderer-text"));
+
+  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (priv->edit_widget));
+  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (priv->edit_widget));
+  priv->edit_widget = NULL;
+  priv->grab_widget = NULL;
+  priv->grab_keyboard = NULL;
+  priv->grab_pointer = NULL;
 
-  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (accel->edit_widget));
-  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (accel->edit_widget));
-  accel->edit_widget = NULL;
-  accel->grab_widget = NULL;
-  
   if (edited)
     g_signal_emit (accel, signals[ACCEL_EDITED], 0, path, 
                   accel_key, accel_mods, event->hardware_keycode);
@@ -471,12 +529,16 @@ static void
 ungrab_stuff (GtkWidget            *widget,
               GtkCellRendererAccel *accel)
 {
-  GdkDisplay *display = gtk_widget_get_display (widget);
+  GtkCellRendererAccelPrivate *priv = accel->priv;
+
+  gtk_device_grab_remove (priv->grab_widget, priv->grab_pointer);
+  gdk_device_ungrab (priv->grab_keyboard, GDK_CURRENT_TIME);
+  gdk_device_ungrab (priv->grab_pointer, GDK_CURRENT_TIME);
 
-  gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
-  gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
+  priv->grab_keyboard = NULL;
+  priv->grab_pointer = NULL;
 
-  g_signal_handlers_disconnect_by_func (G_OBJECT (accel->grab_widget),
+  g_signal_handlers_disconnect_by_func (priv->grab_widget,
                                         G_CALLBACK (grab_key_callback),
                                         accel);
 }
@@ -517,58 +579,95 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer      *cell,
                                        GdkEvent             *event,
                                        GtkWidget            *widget,
                                        const gchar          *path,
-                                       GdkRectangle         *background_area,
-                                       GdkRectangle         *cell_area,
+                                       const GdkRectangle   *background_area,
+                                       const GdkRectangle   *cell_area,
                                        GtkCellRendererState  flags)
 {
+  GtkCellRendererAccelPrivate *priv;
   GtkCellRendererText *celltext;
   GtkCellRendererAccel *accel;
+  GtkStyle *style;
   GtkWidget *label;
   GtkWidget *eventbox;
-  
+  GdkDevice *device, *keyb, *pointer;
+  GdkWindow *window;
+  gboolean editable;
+  guint32 time;
+
   celltext = GTK_CELL_RENDERER_TEXT (cell);
   accel = GTK_CELL_RENDERER_ACCEL (cell);
+  priv = accel->priv;
 
   /* If the cell isn't editable we return NULL. */
-  if (celltext->editable == FALSE)
+  g_object_get (celltext, "editable", &editable, NULL);
+  if (editable == FALSE)
     return NULL;
 
-  g_return_val_if_fail (widget->window != NULL, NULL);
-  
-  if (gdk_keyboard_grab (widget->window, FALSE,
-                         gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+  window = gtk_widget_get_window (widget);
+  style = gtk_widget_get_style (widget);
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  if (event)
+    device = gdk_event_get_device (event);
+  else
+    device = gtk_get_current_event_device ();
+
+  if (!device)
     return NULL;
 
-  if (gdk_pointer_grab (widget->window, FALSE,
-                        GDK_BUTTON_PRESS_MASK,
-                        NULL, NULL,
-                        gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+    {
+      keyb = device;
+      pointer = gdk_device_get_associated_device (device);
+    }
+  else
     {
-      gdk_display_keyboard_ungrab (gtk_widget_get_display (widget),
-                                   gdk_event_get_time (event));
+      pointer = device;
+      keyb = gdk_device_get_associated_device (device);
+    }
+
+  time = gdk_event_get_time (event);
+
+  if (gdk_device_grab (keyb, window,
+                       GDK_OWNERSHIP_WINDOW, FALSE,
+                       GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
+                       NULL, time) != GDK_GRAB_SUCCESS)
+    return NULL;
+
+  if (gdk_device_grab (pointer, window,
+                       GDK_OWNERSHIP_WINDOW, FALSE,
+                       GDK_BUTTON_PRESS_MASK,
+                       NULL, time) != GDK_GRAB_SUCCESS)
+    {
+      gdk_device_ungrab (keyb, time);
       return NULL;
     }
-  
-  accel->grab_widget = widget;
 
-  g_signal_connect (G_OBJECT (widget), "key_press_event",
+  priv->grab_keyboard = keyb;
+  priv->grab_pointer = pointer;
+  priv->grab_widget = widget;
+
+  g_signal_connect (G_OBJECT (widget), "key-press-event",
                     G_CALLBACK (grab_key_callback),
                     accel);
 
   eventbox = g_object_new (_gtk_cell_editable_event_box_get_type (), NULL);
-  accel->edit_widget = eventbox;
-  g_object_add_weak_pointer (G_OBJECT (accel->edit_widget),
-                             (gpointer) &accel->edit_widget);
+  priv->edit_widget = eventbox;
+  g_object_add_weak_pointer (G_OBJECT (priv->edit_widget),
+                             (gpointer) &priv->edit_widget);
   
   label = gtk_label_new (NULL);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
   
+
   gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL,
-                        &widget->style->bg[GTK_STATE_SELECTED]);
+                        &style->bg[GTK_STATE_SELECTED]);
 
   gtk_widget_modify_fg (label, GTK_STATE_NORMAL,
-                        &widget->style->fg[GTK_STATE_SELECTED]);
-  
+                        &style->fg[GTK_STATE_SELECTED]);
+
   /* This label is displayed in a treeview cell displaying
    * an accelerator when the cell is clicked to change the 
    * acelerator.
@@ -577,17 +676,15 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer      *cell,
 
   gtk_container_add (GTK_CONTAINER (eventbox), label);
   
-  g_object_set_data_full (G_OBJECT (accel->edit_widget), "gtk-cell-renderer-text",
+  g_object_set_data_full (G_OBJECT (priv->edit_widget), "gtk-cell-renderer-text",
                           g_strdup (path), g_free);
   
-  gtk_widget_show_all (accel->edit_widget);
+  gtk_widget_show_all (priv->edit_widget);
 
-  g_signal_connect (G_OBJECT (accel->edit_widget), "unrealize",
+  gtk_device_grab_add (priv->grab_widget, pointer, TRUE);
+
+  g_signal_connect (priv->edit_widget, "unrealize",
                     G_CALLBACK (ungrab_stuff), accel);
   
-  return GTK_CELL_EDITABLE (accel->edit_widget);
+  return GTK_CELL_EDITABLE (priv->edit_widget);
 }
-
-
-#define __GTK_CELL_RENDERER_ACCEL_C__
-#include "gtkaliasdef.c"