]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkentry.c
Show lock warning for num lock as well as caps lock
[~andy/gtk] / gtk / gtkentry.c
index c4aeb66c2549056a22211872d15708d0d9c008e7..f0fd92c1db5ba301f81b35bbac5dafb57775c86d 100644 (file)
@@ -139,6 +139,8 @@ struct _GtkEntryPrivate
   gint start_y;
 
   gchar *im_module;
+
+  GdkDevice *completion_device;
 };
 
 typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
@@ -2463,12 +2465,20 @@ static void
 gtk_entry_dispose (GObject *object)
 {
   GtkEntry *entry = GTK_ENTRY (object);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
 
   gtk_entry_set_icon_from_pixbuf (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
   gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
   gtk_entry_set_icon_from_pixbuf (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
   gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
 
+  if (priv->buffer)
+    {
+      buffer_disconnect_signals (entry);
+      g_object_unref (priv->buffer);
+      priv->buffer = NULL;
+    }
+
   G_OBJECT_CLASS (gtk_entry_parent_class)->dispose (object);
 }
 
@@ -2510,11 +2520,6 @@ gtk_entry_finalize (GObject *object)
 
   g_free (priv->im_module);
 
-  /* COMPAT: entry->text is a deprecated field, and the allocation 
-     is owned by the buffer. */
-
-  gtk_entry_set_buffer (entry, NULL);
-
   G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
 }
 
@@ -2674,7 +2679,7 @@ realize_icon_info (GtkWidget            *widget,
                                       attributes_mask);
   gdk_window_set_user_data (icon_info->window, widget);
   gdk_window_set_background (icon_info->window,
-                             &widget->style->base[GTK_WIDGET_STATE (widget)]);
+                             &widget->style->base[gtk_widget_get_state (widget)]);
 
   gtk_widget_queue_resize (widget);
 }
@@ -2796,8 +2801,8 @@ gtk_entry_realize (GtkWidget *widget)
 
   widget->style = gtk_style_attach (widget->style, widget->window);
 
-  gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
-  gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+  gdk_window_set_background (widget->window, &widget->style->base[gtk_widget_get_state (widget)]);
+  gdk_window_set_background (entry->text_area, &widget->style->base[gtk_widget_get_state (widget)]);
 
   gdk_window_show (entry->text_area);
 
@@ -3305,7 +3310,7 @@ gtk_entry_draw_frame (GtkWidget      *widget,
   gtk_widget_style_get (widget, "state-hint", &state_hint, NULL);
   if (state_hint)
       state = gtk_widget_has_focus (widget) ?
-        GTK_STATE_ACTIVE : GTK_WIDGET_STATE (widget);
+        GTK_STATE_ACTIVE : gtk_widget_get_state (widget);
   else
       state = GTK_STATE_NORMAL;
 
@@ -3323,7 +3328,8 @@ gtk_entry_draw_frame (GtkWidget      *widget,
       width += 2 * priv->focus_width;
       height += 2 * priv->focus_width;
       
-      gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), 
+      gtk_paint_focus (widget->style, widget->window,
+                       gtk_widget_get_state (widget),
                       &event->area, widget, "entry",
                       0, 0, width, height);
     }
@@ -3455,9 +3461,9 @@ gtk_entry_expose (GtkWidget      *widget,
   gtk_widget_style_get (widget, "state-hint", &state_hint, NULL);
   if (state_hint)
     state = gtk_widget_has_focus (widget) ?
-      GTK_STATE_ACTIVE : GTK_WIDGET_STATE (widget);
+      GTK_STATE_ACTIVE : gtk_widget_get_state (widget);
   else
-    state = GTK_WIDGET_STATE(widget);
+    state = gtk_widget_get_state(widget);
 
   if (widget->window == event->window)
     {
@@ -3502,7 +3508,7 @@ gtk_entry_expose (GtkWidget      *widget,
               gdk_drawable_get_size (icon_info->window, &width, &height);
 
               gtk_paint_flat_box (widget->style, icon_info->window,
-                                  GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
+                                  gtk_widget_get_state (widget), GTK_SHADOW_NONE,
                                   NULL, widget, "entry_bg",
                                   0, 0, width, height);
 
@@ -4244,13 +4250,13 @@ gtk_entry_state_changed (GtkWidget      *widget,
   
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
-      gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+      gdk_window_set_background (widget->window, &widget->style->base[gtk_widget_get_state (widget)]);
+      gdk_window_set_background (entry->text_area, &widget->style->base[gtk_widget_get_state (widget)]);
       for (i = 0; i < MAX_ICONS; i++) 
         {
           EntryIconInfo *icon_info = priv->icons[i];
           if (icon_info && icon_info->window)
-            gdk_window_set_background (icon_info->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+            gdk_window_set_background (icon_info->window, &widget->style->base[gtk_widget_get_state (widget)]);
         }
 
       if (gtk_widget_is_sensitive (widget))
@@ -4462,13 +4468,13 @@ gtk_entry_style_set (GtkWidget *widget,
 
   if (previous_style && gtk_widget_get_realized (widget))
     {
-      gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
-      gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+      gdk_window_set_background (widget->window, &widget->style->base[gtk_widget_get_state (widget)]);
+      gdk_window_set_background (entry->text_area, &widget->style->base[gtk_widget_get_state (widget)]);
       for (i = 0; i < MAX_ICONS; i++) 
         {
           EntryIconInfo *icon_info = priv->icons[i];
           if (icon_info && icon_info->window)
-            gdk_window_set_background (icon_info->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+            gdk_window_set_background (icon_info->window, &widget->style->base[gtk_widget_get_state (widget)]);
         }
     }
 
@@ -5803,6 +5809,55 @@ _gtk_entry_reset_im_context (GtkEntry *entry)
     }
 }
 
+/**
+ * gtk_entry_reset_im_context:
+ * @entry: a #GtkEntry
+ *
+ * Reset the input method context of the entry if needed.
+ *
+ * This can be necessary in the case where modifying the buffer
+ * would confuse on-going input method behavior.
+ *
+ * Since: 2.22
+ */
+void
+gtk_entry_reset_im_context (GtkEntry *entry)
+{
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  _gtk_entry_reset_im_context (entry);
+}
+
+/**
+ * gtk_entry_im_context_filter_keypress:
+ * @entry: a #GtkEntry
+ * @event: the key event
+ *
+ * Allow the #GtkEntry input method to internally handle key press
+ * and release events. If this function returns %TRUE, then no further
+ * processing should be done for this key event. See
+ * gtk_im_context_filter_keypress().
+ *
+ * Note that you are expected to call this function from your handler
+ * when overriding key event handling. This is needed in the case when
+ * you need to insert your own key handling between the input method
+ * and the default key event handling of the #GtkEntry.
+ * See gtk_text_view_reset_im_context() for an example of use.
+ *
+ * Return value: %TRUE if the input method handled the key event.
+ *
+ * Since: 2.22
+ */
+gboolean
+gtk_entry_im_context_filter_keypress (GtkEntry    *entry,
+                                      GdkEventKey *event)
+{
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
+
+  return gtk_im_context_filter_keypress (entry->im_context, event);
+}
+
+
 static gint
 gtk_entry_find_position (GtkEntry *entry,
                         gint      x)
@@ -6448,38 +6503,41 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
 {
   GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
   EntryIconInfo *icon_info = priv->icons[icon_pos];
-  GdkScreen *screen;
+  GtkIconInfo *info;
   GtkIconTheme *icon_theme;
   GtkSettings *settings;
+  GtkStateType state;
+  GtkWidget *widget;
+  GdkScreen *screen;
   gint width, height;
-  GtkIconInfo *info;
-  gint state;
 
   if (!icon_info || icon_info->pixbuf)
     return;
 
+  widget = GTK_WIDGET (entry);
+
   switch (icon_info->storage_type)
     {
     case GTK_IMAGE_EMPTY:
     case GTK_IMAGE_PIXBUF:
       break;
     case GTK_IMAGE_STOCK:
-      state = GTK_WIDGET_STATE (entry);
-      GTK_WIDGET_STATE (entry) = GTK_STATE_NORMAL;
-      icon_info->pixbuf = gtk_widget_render_icon (GTK_WIDGET (entry),
+      state = gtk_widget_get_state (widget);
+      gtk_widget_set_state (widget, GTK_STATE_NORMAL);
+      icon_info->pixbuf = gtk_widget_render_icon (widget,
                                                   icon_info->stock_id,
                                                   GTK_ICON_SIZE_MENU,
                                                   NULL);
       if (!icon_info->pixbuf)
-        icon_info->pixbuf = gtk_widget_render_icon (GTK_WIDGET (entry),
+        icon_info->pixbuf = gtk_widget_render_icon (widget,
                                                     GTK_STOCK_MISSING_IMAGE,
                                                     GTK_ICON_SIZE_MENU,
                                                     NULL);
-      GTK_WIDGET_STATE (entry) = state;
+      gtk_widget_set_state (widget, state);
       break;
 
     case GTK_IMAGE_ICON_NAME:
-      screen = gtk_widget_get_screen (GTK_WIDGET (entry));
+      screen = gtk_widget_get_screen (widget);
       if (screen)
         {
           icon_theme = gtk_icon_theme_get_for_screen (screen);
@@ -6496,19 +6554,19 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
 
           if (icon_info->pixbuf == NULL)
             {
-              state = GTK_WIDGET_STATE (entry);
-              GTK_WIDGET_STATE (entry) = GTK_STATE_NORMAL;
-              icon_info->pixbuf = gtk_widget_render_icon (GTK_WIDGET (entry),
+              state = gtk_widget_get_state (widget);
+              gtk_widget_set_state (widget, GTK_STATE_NORMAL);
+              icon_info->pixbuf = gtk_widget_render_icon (widget,
                                                           GTK_STOCK_MISSING_IMAGE,
                                                           GTK_ICON_SIZE_MENU,
                                                           NULL);
-              GTK_WIDGET_STATE (entry) = state;
+              gtk_widget_set_state (widget, state);
             }
         }
       break;
 
     case GTK_IMAGE_GICON:
-      screen = gtk_widget_get_screen (GTK_WIDGET (entry));
+      screen = gtk_widget_get_screen (widget);
       if (screen)
         {
           icon_theme = gtk_icon_theme_get_for_screen (screen);
@@ -6530,13 +6588,13 @@ gtk_entry_ensure_pixbuf (GtkEntry             *entry,
 
           if (icon_info->pixbuf == NULL)
             {
-              state = GTK_WIDGET_STATE (entry);
-              GTK_WIDGET_STATE (entry) = GTK_STATE_NORMAL;
-              icon_info->pixbuf = gtk_widget_render_icon (GTK_WIDGET (entry),
+              state = gtk_widget_get_state (widget);
+              gtk_widget_set_state (widget, GTK_STATE_NORMAL);
+              icon_info->pixbuf = gtk_widget_render_icon (widget,
                                                           GTK_STOCK_MISSING_IMAGE,
                                                           GTK_ICON_SIZE_MENU,
                                                           NULL);
-              GTK_WIDGET_STATE (entry) = state;
+              gtk_widget_set_state (widget, state);
             }
         }
       break;
@@ -6584,32 +6642,6 @@ gtk_entry_new_with_buffer (GtkEntryBuffer *buffer)
   return g_object_new (GTK_TYPE_ENTRY, "buffer", buffer, NULL);
 }
 
-/**
- * gtk_entry_new_with_max_length:
- * @max: the maximum length of the entry, or 0 for no maximum.
- *   (other than the maximum length of entries.) The value passed in will
- *   be clamped to the range 0-65536.
- *
- * Creates a new #GtkEntry widget with the given maximum length.
- * 
- * Return value: a new #GtkEntry
- *
- * Deprecated: 2.0: Use gtk_entry_set_max_length() instead.
- **/
-GtkWidget*
-gtk_entry_new_with_max_length (gint max)
-{
-  GtkEntry *entry;
-
-  max = CLAMP (max, 0, GTK_ENTRY_BUFFER_MAX_SIZE);
-
-  entry = g_object_new (GTK_TYPE_ENTRY, NULL);
-  gtk_entry_buffer_set_max_length (get_buffer (entry), max);
-
-  return GTK_WIDGET (entry);
-}
-
-
 static GtkEntryBuffer*
 get_buffer (GtkEntry *entry)
 {
@@ -6704,6 +6736,9 @@ gtk_entry_set_buffer (GtkEntry       *entry,
   g_object_notify (obj, "invisible-char");
   g_object_notify (obj, "invisible-char-set");
   g_object_thaw_notify (obj);
+
+  gtk_editable_set_position (GTK_EDITABLE (entry), 0);
+  gtk_entry_recompute (entry);
 }
 
 /**
@@ -6774,75 +6809,6 @@ gtk_entry_set_text (GtkEntry    *entry,
     g_signal_handler_unblock (entry, completion->priv->changed_id);
 }
 
-/**
- * gtk_entry_append_text:
- * @entry: a #GtkEntry
- * @text: the text to append
- *
- * Appends the given text to the contents of the widget.
- *
- * Deprecated: 2.0: Use gtk_editable_insert_text() instead.
- */
-void
-gtk_entry_append_text (GtkEntry *entry,
-                      const gchar *text)
-{
-  GtkEntryPrivate *priv;
-  gint tmp_pos;
-
-  g_return_if_fail (GTK_IS_ENTRY (entry));
-  g_return_if_fail (text != NULL);
-  priv = GTK_ENTRY_GET_PRIVATE (entry);
-
-  tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry));
-  gtk_editable_insert_text (GTK_EDITABLE (entry), text, -1, &tmp_pos);
-}
-
-/**
- * gtk_entry_prepend_text:
- * @entry: a #GtkEntry
- * @text: the text to prepend
- *
- * Prepends the given text to the contents of the widget.
- *
- * Deprecated: 2.0: Use gtk_editable_insert_text() instead.
- */
-void
-gtk_entry_prepend_text (GtkEntry *entry,
-                       const gchar *text)
-{
-  gint tmp_pos;
-
-  g_return_if_fail (GTK_IS_ENTRY (entry));
-  g_return_if_fail (text != NULL);
-
-  tmp_pos = 0;
-  gtk_editable_insert_text (GTK_EDITABLE (entry), text, -1, &tmp_pos);
-}
-
-/**
- * gtk_entry_set_position:
- * @entry: a #GtkEntry
- * @position: the position of the cursor. The cursor is displayed
- *    before the character with the given (base 0) index in the widget. 
- *    The value must be less than or equal to the number of characters 
- *    in the widget. A value of -1 indicates that the position should
- *    be set after the last character in the entry. Note that this 
- *    position is in characters, not in bytes.
- *
- * Sets the cursor position in an entry to the given value. 
- *
- * Deprecated: 2.0: Use gtk_editable_set_position() instead.
- */
-void
-gtk_entry_set_position (GtkEntry *entry,
-                       gint      position)
-{
-  g_return_if_fail (GTK_IS_ENTRY (entry));
-
-  gtk_editable_set_position (GTK_EDITABLE (entry), position);
-}
-
 /**
  * gtk_entry_set_visibility:
  * @entry: a #GtkEntry
@@ -6983,26 +6949,6 @@ gtk_entry_unset_invisible_char (GtkEntry *entry)
   gtk_entry_recompute (entry);
 }
 
-/**
- * gtk_entry_set_editable:
- * @entry: a #GtkEntry
- * @editable: %TRUE if the user is allowed to edit the text
- *   in the widget
- *
- * Determines if the user can edit the text in the editable
- * widget or not. 
- *
- * Deprecated: 2.0: Use gtk_editable_set_editable() instead.
- */
-void
-gtk_entry_set_editable (GtkEntry *entry,
-                       gboolean  editable)
-{
-  g_return_if_fail (GTK_IS_ENTRY (entry));
-
-  gtk_editable_set_editable (GTK_EDITABLE (entry), editable);
-}
-
 /**
  * gtk_entry_set_overwrite_mode:
  * @entry: a #GtkEntry
@@ -7069,28 +7015,6 @@ gtk_entry_get_text (GtkEntry *entry)
   return gtk_entry_buffer_get_text (get_buffer (entry));
 }
 
-/**
- * gtk_entry_select_region:
- * @entry: a #GtkEntry
- * @start: the starting position
- * @end: the end position
- *
- * Selects a region of text. The characters that are selected are 
- * those characters at positions from @start_pos up to, but not 
- * including @end_pos. If @end_pos is negative, then the the characters 
- * selected will be those characters from @start_pos to the end of 
- * the text. 
- *
- * Deprecated: 2.0: Use gtk_editable_select_region() instead.
- */
-void       
-gtk_entry_select_region  (GtkEntry       *entry,
-                         gint            start,
-                         gint            end)
-{
-  gtk_editable_select_region (GTK_EDITABLE (entry), start, end);
-}
-
 /**
  * gtk_entry_set_max_length:
  * @entry: a #GtkEntry
@@ -9235,6 +9159,7 @@ static gint
 gtk_entry_completion_timeout (gpointer data)
 {
   GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (completion->priv->entry);
 
   completion->priv->completion_timeout = 0;
 
@@ -9264,7 +9189,7 @@ gtk_entry_completion_timeout (gpointer data)
          if (gtk_widget_get_visible (completion->priv->popup_window))
            _gtk_entry_completion_resize_popup (completion);
           else
-           _gtk_entry_completion_popup (completion);
+           _gtk_entry_completion_popup (completion, priv->completion_device);
        }
       else 
        _gtk_entry_completion_popdown (completion);
@@ -9393,6 +9318,7 @@ gtk_entry_completion_key_press (GtkWidget   *widget,
             {
 
               GtkTreeIter iter;
+              GtkTreeIter child_iter;
               GtkTreeModel *model = NULL;
               GtkTreeSelection *sel;
               gboolean entry_set;
@@ -9400,12 +9326,15 @@ gtk_entry_completion_key_press (GtkWidget   *widget,
               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view));
               if (!gtk_tree_selection_get_selected (sel, &model, &iter))
                 return FALSE;
+
+              gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
+              model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
               
               if (completion->priv->completion_prefix == NULL)
                 completion->priv->completion_prefix = g_strdup (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry)));
 
               g_signal_emit_by_name (completion, "cursor-on-match", model,
-                                     &iter, &entry_set);
+                                     &child_iter, &entry_set);
             }
         }
       else if (completion->priv->current_selected - matches >= 0)
@@ -9565,7 +9494,9 @@ static void
 gtk_entry_completion_changed (GtkWidget *entry,
                               gpointer   user_data)
 {
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
   GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
+  GdkDevice *device;
 
   /* (re)install completion timeout */
   if (completion->priv->completion_timeout)
@@ -9583,6 +9514,14 @@ gtk_entry_completion_changed (GtkWidget *entry,
       return;
     }
 
+  device = gtk_get_current_event_device ();
+
+  if (device && device->source == GDK_SOURCE_KEYBOARD)
+    device = gdk_device_get_associated_device (device);
+
+  if (device)
+    priv->completion_device = device;
+
   completion->priv->completion_timeout =
     gdk_threads_add_timeout (COMPLETION_TIMEOUT,
                    gtk_entry_completion_timeout,
@@ -10077,7 +10016,12 @@ keymap_state_changed (GdkKeymap *keymap,
 
   if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL && priv->caps_lock_warning)
     { 
-      if (gdk_keymap_get_caps_lock_state (keymap))
+      if (gdk_keymap_get_num_lock_state (keymap)
+          && gdk_keymap_get_caps_lock_state (keymap))
+        text = _("Caps Lock and Num Lock are on");
+      else if (gdk_keymap_get_num_lock_state (keymap))
+        text = _("Num Lock is on");
+      else if (gdk_keymap_get_caps_lock_state (keymap))
         text = _("Caps Lock is on");
     }