/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* GTK - The GIMP Toolkit
* Copyright ( C ) 1995 - 1997 Peter Mattis , Spencer Kimball and Josh MacDonald
* Copyright ( C ) 2004 - 2006 Christian Hammond
* Copyright ( C ) 2008 Cody Russell
* Copyright ( C ) 2008 Red Hat , Inc .
*
* 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 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/>.
*/
/*
* Modified by the GTK + Team and others 1997 - 2000 . See the AUTHORS
* file for a list of people on the GTK + Team . See the ChangeLog
* files for a list of changes . These files are distributed with
* GTK + at ftp : //ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gtkentryprivate.h"
#include "gtkaccessibleprivate.h"
#include "gtkadjustment.h"
#include "deprecated/gtkcelleditable.h"
#include "gtkdebug.h"
#include "gtkeditable.h"
#include "gtkemojichooser.h"
#include "gtkemojicompletionprivate.h"
#include "gtkentrybuffer.h"
#include "gtkgesturedrag.h"
#include <glib/gi18n-lib.h>
#include "gtkjoinedmenuprivate.h"
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkpangoprivate.h"
#include "gtkprivate.h"
#include "gtkprogressbar.h"
#include "gtksnapshot.h"
#include "gtktextprivate.h"
#include "gtktextutilprivate.h"
#include "gtktooltip.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gtknative.h"
#include "gtkgestureclick.h"
#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkwidgetpaintable.h"
#include "gtkbuilderprivate.h"
#include <cairo-gobject.h>
#include <string.h>
/**
* GtkEntry :
*
* A single - line text entry widget .
*
* < picture >
* < source srcset = " entry - dark . png " media = " ( prefers - color - scheme : dark ) " >
* < img alt = " An example GtkEntry " src = " entry . png " >
* < / picture >
*
* A fairly large set of key bindings are supported by default . If the
* entered text is longer than the allocation of the widget , the widget
* will scroll so that the cursor position is visible .
*
* When using an entry for passwords and other sensitive information , it
* can be put into “ password mode ” using [ method @ Gtk . Entry . set_visibility ] .
* In this mode , entered text is displayed using a “ invisible ” character .
* By default , GTK picks the best invisible character that is available
* in the current font , but it can be changed with
* [ method @ Gtk . Entry . set_invisible_char ] .
*
* ` GtkEntry ` has the ability to display progress or activity
* information behind the text . To make an entry display such information ,
* use [ method @ Gtk . Entry . set_progress_fraction ] or
* [ method @ Gtk . Entry . set_progress_pulse_step ] .
*
* Additionally , ` GtkEntry ` can show icons at either side of the entry .
* These icons can be activatable by clicking , can be set up as drag source
* and can have tooltips . To add an icon , use
* [ method @ Gtk . Entry . set_icon_from_gicon ] or one of the various other functions
* that set an icon from an icon name or a paintable . To trigger an action when
* the user clicks an icon , connect to the [ signal @ Gtk . Entry : : icon - press ] signal .
* To allow DND operations from an icon , use
* [ method @ Gtk . Entry . set_icon_drag_source ] . To set a tooltip on an icon , use
* [ method @ Gtk . Entry . set_icon_tooltip_text ] or the corresponding function
* for markup .
*
* Note that functionality or information that is only available by clicking
* on an icon in an entry may not be accessible at all to users which are not
* able to use a mouse or other pointing device . It is therefore recommended
* that any such functionality should also be available by other means , e . g .
* via the context menu of the entry .
*
* # CSS nodes
*
* ` ` `
* entry [ . flat ] [ . warning ] [ . error ]
* ├ ─ ─ text [ . readonly ]
* ├ ─ ─ image . left
* ├ ─ ─ image . right
* ╰ ─ ─ [ progress [ . pulse ] ]
* ` ` `
*
* ` GtkEntry ` has a main node with the name entry . Depending on the properties
* of the entry , the style classes . read - only and . flat may appear . The style
* classes . warning and . error may also be used with entries .
*
* When the entry shows icons , it adds subnodes with the name image and the
* style class . left or . right , depending on where the icon appears .
*
* When the entry shows progress , it adds a subnode with the name progress .
* The node has the style class . pulse when the shown progress is pulsing .
*
* For all the subnodes added to the text node in various situations ,
* see [ class @ Gtk . Text ] .
*
* # GtkEntry as GtkBuildable
*
* The ` GtkEntry ` implementation of the ` GtkBuildable ` interface supports a
* custom ` < attributes > ` element , which supports any number of ` < attribute > `
* elements . The ` < attribute > ` element has attributes named “ name “ , “ value “ ,
* “ start “ and “ end “ and allows you to specify ` PangoAttribute ` values for
* this label .
*
* An example of a UI definition fragment specifying Pango attributes :
* ` ` ` xml
* < object class = " GtkEntry " >
* < attributes >
* < attribute name = " weight " value = " PANGO_WEIGHT_BOLD " / >
* < attribute name = " background " value = " red " start = " 5 " end = " 10 " / >
* < / attributes >
* < / object >
* ` ` `
*
* The start and end attributes specify the range of characters to which the
* Pango attribute applies . If start and end are not specified , the attribute
* is applied to the whole text . Note that specifying ranges does not make much
* sense with translatable attributes . Use markup embedded in the translatable
* content instead .
*
* # Accessibility
*
* ` GtkEntry ` uses the [ enum @ Gtk . AccessibleRole . text_box ] role .
*/
#define MAX_ICONS 2
#define IS_VALID_ICON_POSITION(pos) \
((pos) == GTK_ENTRY_ICON_PRIMARY || \
(pos) == GTK_ENTRY_ICON_SECONDARY)
static GQuark quark_entry_completion = 0 ;
typedef struct _EntryIconInfo EntryIconInfo;
typedef struct _GtkEntryPrivate GtkEntryPrivate;
struct _GtkEntryPrivate
{
EntryIconInfo *icons[MAX_ICONS];
GtkWidget *text;
GtkWidget *progress_widget;
GMenuModel *extra_menu;
gchar *menu_entry_icon_primary_text;
gchar *menu_entry_icon_secondary_text;
guint show_emoji_icon : 1 ;
guint editing_canceled : 1 ; /* Only used by GtkCellRendererText */
};
struct _EntryIconInfo
{
GtkWidget *widget;
char *tooltip;
guint nonactivatable : 1 ;
guint in_drag : 1 ;
GdkDragAction actions;
GdkContentProvider *content;
};
enum {
ACTIVATE,
ICON_PRESS,
ICON_RELEASE,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_BUFFER,
PROP_MAX_LENGTH,
PROP_VISIBILITY,
PROP_HAS_FRAME,
PROP_INVISIBLE_CHAR,
PROP_ACTIVATES_DEFAULT,
PROP_SCROLL_OFFSET,
PROP_TRUNCATE_MULTILINE,
PROP_OVERWRITE_MODE,
PROP_TEXT_LENGTH,
PROP_INVISIBLE_CHAR_SET,
PROP_PROGRESS_FRACTION,
PROP_PROGRESS_PULSE_STEP,
PROP_PAINTABLE_PRIMARY,
PROP_PAINTABLE_SECONDARY,
PROP_ICON_NAME_PRIMARY,
PROP_ICON_NAME_SECONDARY,
PROP_GICON_PRIMARY,
PROP_GICON_SECONDARY,
PROP_STORAGE_TYPE_PRIMARY,
PROP_STORAGE_TYPE_SECONDARY,
PROP_ACTIVATABLE_PRIMARY,
PROP_ACTIVATABLE_SECONDARY,
PROP_SENSITIVE_PRIMARY,
PROP_SENSITIVE_SECONDARY,
PROP_TOOLTIP_TEXT_PRIMARY,
PROP_TOOLTIP_TEXT_SECONDARY,
PROP_TOOLTIP_MARKUP_PRIMARY,
PROP_TOOLTIP_MARKUP_SECONDARY,
PROP_IM_MODULE,
PROP_PLACEHOLDER_TEXT,
PROP_COMPLETION,
PROP_INPUT_PURPOSE,
PROP_INPUT_HINTS,
PROP_ATTRIBUTES,
PROP_TABS,
PROP_EXTRA_MENU,
PROP_SHOW_EMOJI_ICON,
PROP_ENABLE_EMOJI_COMPLETION,
PROP_MENU_ENTRY_ICON_PRIMARY_TEXT,
PROP_MENU_ENTRY_ICON_SECONDARY_TEXT,
/* GtkCellEditable */
PROP_EDITING_CANCELED,
NUM_PROPERTIES
};
static GParamSpec *entry_props[NUM_PROPERTIES] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
typedef enum {
CURSOR_STANDARD,
CURSOR_DND
} CursorType;
typedef enum
{
DISPLAY_NORMAL, /* The entry text is being shown */
DISPLAY_INVISIBLE, /* In invisible mode, text replaced by (eg) bullets */
DISPLAY_BLANK /* In invisible mode, nothing shown at all */
} DisplayMode;
/* GObject methods
*/
static void gtk_entry_editable_init (GtkEditableInterface *iface);
static void gtk_entry_cell_editable_init (GtkCellEditableIface *iface);
static void gtk_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_entry_finalize (GObject *object);
static void gtk_entry_dispose (GObject *object);
/* GtkWidget methods
*/
static void gtk_entry_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline);
static void gtk_entry_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static gboolean gtk_entry_query_tooltip (GtkWidget *widget,
int x,
int y,
gboolean keyboard_tip,
GtkTooltip *tooltip);
static void gtk_entry_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir);
/* GtkCellEditable method implementations
*/
static void gtk_entry_start_editing (GtkCellEditable *cell_editable,
GdkEvent *event);
static void update_extra_menu (GtkEntry *entry);
/* Default signal handlers
*/
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
static void set_show_emoji_icon (GtkEntry *entry,
gboolean value);
static void gtk_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static GtkBuildableIface *buildable_parent_iface = NULL;
static void gtk_entry_buildable_interface_init (GtkBuildableIface *iface);
static void gtk_entry_accessible_interface_init (GtkAccessibleInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkEntry)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE,
gtk_entry_accessible_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_entry_buildable_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
gtk_entry_editable_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE,
gtk_entry_cell_editable_init))
/* Implement the GtkAccessible interface, in order to obtain focus
* state from the GtkText widget that we are wrapping . The GtkText
* widget is ignored for accessibility purposes ( it has role NONE ) ,
* and any a11y text functionality is implemented for GtkEntry and
* similar wrappers ( GtkPasswordEntry , GtkSpinButton , etc ) .
*/
static gboolean
gtk_entry_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void
gtk_entry_accessible_interface_init (GtkAccessibleInterface *iface)
{
GtkAccessibleInterface *parent_iface = g_type_interface_peek_parent (iface);
iface->get_at_context = parent_iface->get_at_context;
iface->get_platform_state = gtk_entry_accessible_get_platform_state;
}
static const GtkBuildableParser pango_parser =
{
gtk_pango_attribute_start_element,
};
static gboolean
gtk_entry_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *tagname,
GtkBuildableParser *parser,
gpointer *data)
{
if (buildable_parent_iface->custom_tag_start (buildable, builder, child,
tagname, parser, data))
return TRUE ;
if (strcmp (tagname, "attributes" ) == 0 )
{
GtkPangoAttributeParserData *parser_data;
gtk_buildable_tag_deprecation_warning (buildable, builder, "attributes" , "attributes" );
parser_data = g_new0 (GtkPangoAttributeParserData, 1 );
parser_data->builder = g_object_ref (builder);
parser_data->object = (GObject *) g_object_ref (buildable);
*parser = pango_parser;
*data = parser_data;
return TRUE ;
}
return FALSE ;
}
static void
gtk_entry_buildable_custom_finished (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *tagname,
gpointer user_data)
{
GtkPangoAttributeParserData *data = user_data;
buildable_parent_iface->custom_finished (buildable, builder, child,
tagname, user_data);
if (strcmp (tagname, "attributes" ) == 0 )
{
if (data->attrs)
{
gtk_entry_set_attributes (GTK_ENTRY (buildable), data->attrs);
pango_attr_list_unref (data->attrs);
}
g_object_unref (data->object);
g_object_unref (data->builder);
g_free (data);
}
}
static void
gtk_entry_buildable_interface_init (GtkBuildableIface *iface)
{
buildable_parent_iface = g_type_interface_peek_parent (iface);
iface->custom_tag_start = gtk_entry_buildable_custom_tag_start;
iface->custom_finished = gtk_entry_buildable_custom_finished;
}
static gboolean
gtk_entry_grab_focus (GtkWidget *widget)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
return gtk_widget_grab_focus (priv->text);
}
static gboolean
gtk_entry_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->text);
return TRUE ;
}
static void
gtk_entry_activate_misc_icon (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GtkEntry *self = GTK_ENTRY (widget);
gtk_entry_activate_icon (self,
g_str_equal (action_name, "misc.menu_entry_icon_primary" )
? GTK_ENTRY_ICON_PRIMARY
: GTK_ENTRY_ICON_SECONDARY);
}
static void
gtk_entry_class_init (GtkEntryClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class );
GtkWidgetClass *widget_class;
widget_class = (GtkWidgetClass*) class ;
gobject_class->dispose = gtk_entry_dispose;
gobject_class->finalize = gtk_entry_finalize;
gobject_class->set_property = gtk_entry_set_property;
gobject_class->get_property = gtk_entry_get_property;
widget_class->measure = gtk_entry_measure;
widget_class->size_allocate = gtk_entry_size_allocate;
widget_class->snapshot = gtk_entry_snapshot;
widget_class->query_tooltip = gtk_entry_query_tooltip;
widget_class->direction_changed = gtk_entry_direction_changed;
widget_class->grab_focus = gtk_entry_grab_focus;
widget_class->focus = gtk_widget_focus_child;
widget_class->mnemonic_activate = gtk_entry_mnemonic_activate;
quark_entry_completion = g_quark_from_static_string ("gtk-entry-completion-key" );
/**
* GtkEntry : buffer :
*
* The buffer object which actually stores the text .
*/
entry_props[PROP_BUFFER] =
g_param_spec_object ("buffer" , NULL, NULL,
GTK_TYPE_ENTRY_BUFFER,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : max - length :
*
* Maximum number of characters for this entry .
*/
entry_props[PROP_MAX_LENGTH] =
g_param_spec_int ("max-length" , NULL, NULL,
0 , GTK_ENTRY_BUFFER_MAX_SIZE,
0 ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : visibility :
*
* Whether the entry should show the “ invisible char ” instead of the
* actual text ( “ password mode ” ) .
*/
entry_props[PROP_VISIBILITY] =
g_param_spec_boolean ("visibility" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : has - frame :
*
* Whether the entry should draw a frame .
*/
entry_props[PROP_HAS_FRAME] =
g_param_spec_boolean ("has-frame" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : invisible - char :
*
* The character to use when masking entry contents ( “ password mode ” ) .
*/
entry_props[PROP_INVISIBLE_CHAR] =
g_param_spec_unichar ("invisible-char" , NULL, NULL,
'*' ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : activates - default :
*
* Whether to activate the default widget when Enter is pressed .
*/
entry_props[PROP_ACTIVATES_DEFAULT] =
g_param_spec_boolean ("activates-default" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : scroll - offset :
*
* Number of pixels of the entry scrolled off the screen to the left .
*/
entry_props[PROP_SCROLL_OFFSET] =
g_param_spec_int ("scroll-offset" , NULL, NULL,
0 , G_MAXINT,
0 ,
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : truncate - multiline :
*
* When % TRUE , pasted multi - line text is truncated to the first line .
*/
entry_props[PROP_TRUNCATE_MULTILINE] =
g_param_spec_boolean ("truncate-multiline" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : overwrite - mode :
*
* If text is overwritten when typing in the ` GtkEntry ` .
*/
entry_props[PROP_OVERWRITE_MODE] =
g_param_spec_boolean ("overwrite-mode" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : text - length :
*
* The length of the text in the ` GtkEntry ` .
*/
entry_props[PROP_TEXT_LENGTH] =
g_param_spec_uint ("text-length" , NULL, NULL,
0 , G_MAXUINT16,
0 ,
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
/**
* GtkEntry : invisible - char - set :
*
* Whether the invisible char has been set for the ` GtkEntry ` .
*/
entry_props[PROP_INVISIBLE_CHAR_SET] =
g_param_spec_boolean ("invisible-char-set" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
/**
* GtkEntry : progress - fraction :
*
* The current fraction of the task that ' s been completed .
*/
entry_props[PROP_PROGRESS_FRACTION] =
g_param_spec_double ("progress-fraction" , NULL, NULL,
0 .0 , 1 .0 ,
0 .0 ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : progress - pulse - step :
*
* The fraction of total entry width to move the progress
* bouncing block for each pulse .
*
* See [ method @ Gtk . Entry . progress_pulse ] .
*/
entry_props[PROP_PROGRESS_PULSE_STEP] =
g_param_spec_double ("progress-pulse-step" , NULL, NULL,
0 .0 , 1 .0 ,
0 .0 ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : placeholder - text :
*
* The text that will be displayed in the ` GtkEntry ` when it is empty
* and unfocused .
*/
entry_props[PROP_PLACEHOLDER_TEXT] =
g_param_spec_string ("placeholder-text" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - paintable :
*
* A ` GdkPaintable ` to use as the primary icon for the entry .
*/
entry_props[PROP_PAINTABLE_PRIMARY] =
g_param_spec_object ("primary-icon-paintable" , NULL, NULL,
GDK_TYPE_PAINTABLE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - paintable :
*
* A ` GdkPaintable ` to use as the secondary icon for the entry .
*/
entry_props[PROP_PAINTABLE_SECONDARY] =
g_param_spec_object ("secondary-icon-paintable" , NULL, NULL,
GDK_TYPE_PAINTABLE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - name :
*
* The icon name to use for the primary icon for the entry .
*/
entry_props[PROP_ICON_NAME_PRIMARY] =
g_param_spec_string ("primary-icon-name" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - name :
*
* The icon name to use for the secondary icon for the entry .
*/
entry_props[PROP_ICON_NAME_SECONDARY] =
g_param_spec_string ("secondary-icon-name" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - gicon :
*
* The ` GIcon ` to use for the primary icon for the entry .
*/
entry_props[PROP_GICON_PRIMARY] =
g_param_spec_object ("primary-icon-gicon" , NULL, NULL,
G_TYPE_ICON,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - gicon :
*
* The ` GIcon ` to use for the secondary icon for the entry .
*/
entry_props[PROP_GICON_SECONDARY] =
g_param_spec_object ("secondary-icon-gicon" , NULL, NULL,
G_TYPE_ICON,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - storage - type :
*
* The representation which is used for the primary icon of the entry .
*/
entry_props[PROP_STORAGE_TYPE_PRIMARY] =
g_param_spec_enum ("primary-icon-storage-type" , NULL, NULL,
GTK_TYPE_IMAGE_TYPE,
GTK_IMAGE_EMPTY,
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
/**
* GtkEntry : secondary - icon - storage - type :
*
* The representation which is used for the secondary icon of the entry .
*/
entry_props[PROP_STORAGE_TYPE_SECONDARY] =
g_param_spec_enum ("secondary-icon-storage-type" , NULL, NULL,
GTK_TYPE_IMAGE_TYPE,
GTK_IMAGE_EMPTY,
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
/**
* GtkEntry : primary - icon - activatable :
*
* Whether the primary icon is activatable .
*
* GTK emits the [ signal @ Gtk . Entry : : icon - press ] and
* [ signal @ Gtk . Entry : : icon - release ] signals only on sensitive ,
* activatable icons .
*
* Sensitive , but non - activatable icons can be used for purely
* informational purposes .
*/
entry_props[PROP_ACTIVATABLE_PRIMARY] =
g_param_spec_boolean ("primary-icon-activatable" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - activatable :
*
* Whether the secondary icon is activatable .
*
* GTK emits the [ signal @ Gtk . Entry : : icon - press ] and
* [ signal @ Gtk . Entry : : icon - release ] signals only on sensitive ,
* activatable icons .
*
* Sensitive , but non - activatable icons can be used for purely
* informational purposes .
*/
entry_props[PROP_ACTIVATABLE_SECONDARY] =
g_param_spec_boolean ("secondary-icon-activatable" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - sensitive :
*
* Whether the primary icon is sensitive .
*
* An insensitive icon appears grayed out . GTK does not emit the
* [ signal @ Gtk . Entry : : icon - press ] and [ signal @ Gtk . Entry : : icon - release ]
* signals and does not allow DND from insensitive icons .
*
* An icon should be set insensitive if the action that would trigger
* when clicked is currently not available .
*/
entry_props[PROP_SENSITIVE_PRIMARY] =
g_param_spec_boolean ("primary-icon-sensitive" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - sensitive :
*
* Whether the secondary icon is sensitive .
*
* An insensitive icon appears grayed out . GTK does not emit the
* [ signal @ Gtk . Entry : : icon - press [ and [ signal @ Gtk . Entry : : icon - release ]
* signals and does not allow DND from insensitive icons .
*
* An icon should be set insensitive if the action that would trigger
* when clicked is currently not available .
*/
entry_props[PROP_SENSITIVE_SECONDARY] =
g_param_spec_boolean ("secondary-icon-sensitive" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - tooltip - text :
*
* The contents of the tooltip on the primary icon .
*
* Also see [ method @ Gtk . Entry . set_icon_tooltip_text ] .
*/
entry_props[PROP_TOOLTIP_TEXT_PRIMARY] =
g_param_spec_string ("primary-icon-tooltip-text" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - tooltip - text :
*
* The contents of the tooltip on the secondary icon .
*
* Also see [ method @ Gtk . Entry . set_icon_tooltip_text ] .
*/
entry_props[PROP_TOOLTIP_TEXT_SECONDARY] =
g_param_spec_string ("secondary-icon-tooltip-text" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : primary - icon - tooltip - markup :
*
* The contents of the tooltip on the primary icon , with markup .
*
* Also see [ method @ Gtk . Entry . set_icon_tooltip_markup ] .
*/
entry_props[PROP_TOOLTIP_MARKUP_PRIMARY] =
g_param_spec_string ("primary-icon-tooltip-markup" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : secondary - icon - tooltip - markup :
*
* The contents of the tooltip on the secondary icon , with markup .
*
* Also see [ method @ Gtk . Entry . set_icon_tooltip_markup ] .
*/
entry_props[PROP_TOOLTIP_MARKUP_SECONDARY] =
g_param_spec_string ("secondary-icon-tooltip-markup" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : im - module :
*
* Which IM ( input method ) module should be used for this entry .
*
* See [ class @ Gtk . IMContext ] .
*
* Setting this to a non - % NULL value overrides the system - wide IM
* module setting . See the GtkSettings [ property @ Gtk . Settings : gtk - im - module ]
* property .
*/
entry_props[PROP_IM_MODULE] =
g_param_spec_string ("im-module" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : completion :
*
* The auxiliary completion object to use with the entry .
*
* Deprecated : 4 . 10 : GtkEntryCompletion will be removed in GTK 5 .
*/
entry_props[PROP_COMPLETION] =
g_param_spec_object ("completion" , NULL, NULL,
GTK_TYPE_ENTRY_COMPLETION,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_DEPRECATED);
/**
* GtkEntry : input - purpose :
*
* The purpose of this text field .
*
* This property can be used by on - screen keyboards and other input
* methods to adjust their behaviour .
*
* Note that setting the purpose to % GTK_INPUT_PURPOSE_PASSWORD or
* % GTK_INPUT_PURPOSE_PIN is independent from setting
* [ property @ Gtk . Entry : visibility ] .
*/
entry_props[PROP_INPUT_PURPOSE] =
g_param_spec_enum ("input-purpose" , NULL, NULL,
GTK_TYPE_INPUT_PURPOSE,
GTK_INPUT_PURPOSE_FREE_FORM,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : input - hints :
*
* Additional hints that allow input methods to fine - tune their behavior .
*
* Also see [ property @ Gtk . Entry : input - purpose ]
*/
entry_props[PROP_INPUT_HINTS] =
g_param_spec_flags ("input-hints" , NULL, NULL,
GTK_TYPE_INPUT_HINTS,
GTK_INPUT_HINT_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : attributes :
*
* A list of Pango attributes to apply to the text of the entry .
*
* This is mainly useful to change the size or weight of the text .
*
* The ` PangoAttribute ` ' s @ start_index and @ end_index must refer to the
* [ class @ Gtk . EntryBuffer ] text , i . e . without the preedit string .
*/
entry_props[PROP_ATTRIBUTES] =
g_param_spec_boxed ("attributes" , NULL, NULL,
PANGO_TYPE_ATTR_LIST,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : tabs :
*
* A list of tabstops to apply to the text of the entry .
*/
entry_props[PROP_TABS] =
g_param_spec_boxed ("tabs" , NULL, NULL,
PANGO_TYPE_TAB_ARRAY,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : show - emoji - icon :
*
* Whether the entry will show an Emoji icon in the secondary icon position
* to open the Emoji chooser .
*/
entry_props[PROP_SHOW_EMOJI_ICON] =
g_param_spec_boolean ("show-emoji-icon" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : extra - menu :
*
* A menu model whose contents will be appended to the context menu .
*/
entry_props[PROP_EXTRA_MENU] =
g_param_spec_object ("extra-menu" , NULL, NULL,
G_TYPE_MENU_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : enable - emoji - completion :
*
* Whether to suggest Emoji replacements for : - delimited names
* like ` : heart : ` .
*/
entry_props[PROP_ENABLE_EMOJI_COMPLETION] =
g_param_spec_boolean ("enable-emoji-completion" , NULL, NULL,
FALSE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : menu - entry - icon - primary - text :
*
* Text for an item in the context menu to activate the primary icon action .
*
* When the primary icon is activatable and this property has been set , a new entry
* in the context menu of this GtkEntry will appear with this text . Selecting that
* menu entry will result in the primary icon being activated , exactly in the same way
* as it would be activated from a mouse click .
*
* This simplifies adding accessibility support to applications using activatable
* icons . The activatable icons aren ' t focusable when navigating the interface with
* the keyboard This is why Gtk recommends to also add those actions in the context
* menu . This set of methods greatly simplifies this , by adding a menu item that , when
* enabled , calls the same callback than clicking on the icon .
*
* Since : 4 . 20
*/
entry_props[PROP_MENU_ENTRY_ICON_PRIMARY_TEXT] =
g_param_spec_string ("menu-entry-icon-primary-text" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEntry : menu - entry - icon - secondary - text :
*
* Text for an item in the context menu to activate the secondary icon action .
*
* When the primary icon is activatable and this property has been set , a new entry
* in the context menu of this GtkEntry will appear with this text . Selecting that
* menu entry will result in the primary icon being activated , exactly in the same way
* as it would be activated from a mouse click .
*
* This simplifies adding accessibility support to applications using activatable
* icons . The activatable icons aren ' t focusable when navigating the interface with
* the keyboard This is why Gtk recommends to also add those actions in the context
* menu . This set of methods greatly simplifies this , by adding a menu item that , when
* enabled , calls the same callback than clicking on the icon .
*
* Since : 4 . 20
*/
entry_props[PROP_MENU_ENTRY_ICON_SECONDARY_TEXT] =
g_param_spec_string ("menu-entry-icon-secondary-text" , NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
entry_props[PROP_EDITING_CANCELED] = g_param_spec_override ("editing-canceled" ,
g_object_interface_find_property (g_type_default_interface_ref (GTK_TYPE_CELL_EDITABLE), "editing-canceled" ));
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, entry_props);
gtk_editable_install_properties (gobject_class, NUM_PROPERTIES);
/**
* GtkEntry : : activate :
* @ self : The widget on which the signal is emitted
*
* Emitted when the entry is activated .
*
* The keybindings for this signal are all forms of the Enter key .
*/
signals[ACTIVATE] =
g_signal_new (I_("activate" ),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkEntryClass, activate),
NULL, NULL,
NULL,
G_TYPE_NONE, 0 );
/**
* GtkEntry : : icon - press :
* @ entry : The entry on which the signal is emitted
* @ icon_pos : The position of the clicked icon
*
* Emitted when an activatable icon is clicked .
*/
signals[ICON_PRESS] =
g_signal_new (I_("icon-press" ),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0 ,
NULL, NULL,
NULL,
G_TYPE_NONE, 1 ,
GTK_TYPE_ENTRY_ICON_POSITION);
/**
* GtkEntry : : icon - release :
* @ entry : The entry on which the signal is emitted
* @ icon_pos : The position of the clicked icon
*
* Emitted on the button release from a mouse click
* over an activatable icon .
*/
signals[ICON_RELEASE] =
g_signal_new (I_("icon-release" ),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0 ,
NULL, NULL,
NULL,
G_TYPE_NONE, 1 ,
GTK_TYPE_ENTRY_ICON_POSITION);
gtk_widget_class_set_css_name (widget_class, I_("entry" ));
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TEXT_BOX);
gtk_widget_class_install_action (widget_class, "misc.menu_entry_icon_primary" , NULL,
gtk_entry_activate_misc_icon);
gtk_widget_class_install_action (widget_class, "misc.menu_entry_icon_secondary" , NULL,
gtk_entry_activate_misc_icon);
}
static GtkEditable *
gtk_entry_get_delegate (GtkEditable *editable)
{
GtkEntry *entry = GTK_ENTRY (editable);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
return GTK_EDITABLE (priv->text);
}
static void
gtk_entry_editable_init (GtkEditableInterface *iface)
{
iface->get_delegate = gtk_entry_get_delegate;
}
static void
gtk_entry_cell_editable_init (GtkCellEditableIface *iface)
{
iface->start_editing = gtk_entry_start_editing;
}
static void
gtk_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkEntry *entry = GTK_ENTRY (object);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (gtk_editable_delegate_set_property (object, prop_id, value, pspec))
{
if (prop_id == NUM_PROPERTIES + GTK_EDITABLE_PROP_EDITABLE)
{
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_READ_ONLY, !g_value_get_boolean (value),
-1 );
}
return ;
}
switch (prop_id)
{
case PROP_BUFFER:
case PROP_MAX_LENGTH:
case PROP_VISIBILITY:
case PROP_INVISIBLE_CHAR:
case PROP_INVISIBLE_CHAR_SET:
case PROP_ACTIVATES_DEFAULT:
case PROP_TRUNCATE_MULTILINE:
case PROP_OVERWRITE_MODE:
case PROP_IM_MODULE:
case PROP_INPUT_PURPOSE:
case PROP_INPUT_HINTS:
case PROP_ATTRIBUTES:
case PROP_TABS:
case PROP_ENABLE_EMOJI_COMPLETION:
g_object_set_property (G_OBJECT (priv->text), pspec->name, value);
break ;
case PROP_PLACEHOLDER_TEXT:
gtk_entry_set_placeholder_text (entry, g_value_get_string (value));
break ;
case PROP_HAS_FRAME:
gtk_entry_set_has_frame (entry, g_value_get_boolean (value));
break ;
case PROP_PROGRESS_FRACTION:
gtk_entry_set_progress_fraction (entry, g_value_get_double (value));
break ;
case PROP_PROGRESS_PULSE_STEP:
gtk_entry_set_progress_pulse_step (entry, g_value_get_double (value));
break ;
case PROP_PAINTABLE_PRIMARY:
gtk_entry_set_icon_from_paintable (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_object (value));
break ;
case PROP_PAINTABLE_SECONDARY:
gtk_entry_set_icon_from_paintable (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_object (value));
break ;
case PROP_ICON_NAME_PRIMARY:
gtk_entry_set_icon_from_icon_name (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_string (value));
break ;
case PROP_ICON_NAME_SECONDARY:
gtk_entry_set_icon_from_icon_name (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_string (value));
break ;
case PROP_GICON_PRIMARY:
gtk_entry_set_icon_from_gicon (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_object (value));
break ;
case PROP_GICON_SECONDARY:
gtk_entry_set_icon_from_gicon (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_object (value));
break ;
case PROP_ACTIVATABLE_PRIMARY:
gtk_entry_set_icon_activatable (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_boolean (value));
break ;
case PROP_ACTIVATABLE_SECONDARY:
gtk_entry_set_icon_activatable (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_boolean (value));
break ;
case PROP_SENSITIVE_PRIMARY:
gtk_entry_set_icon_sensitive (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_boolean (value));
break ;
case PROP_SENSITIVE_SECONDARY:
gtk_entry_set_icon_sensitive (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_boolean (value));
break ;
case PROP_TOOLTIP_TEXT_PRIMARY:
gtk_entry_set_icon_tooltip_text (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_string (value));
break ;
case PROP_TOOLTIP_TEXT_SECONDARY:
gtk_entry_set_icon_tooltip_text (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_string (value));
break ;
case PROP_TOOLTIP_MARKUP_PRIMARY:
gtk_entry_set_icon_tooltip_markup (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_string (value));
break ;
case PROP_TOOLTIP_MARKUP_SECONDARY:
gtk_entry_set_icon_tooltip_markup (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_string (value));
break ;
case PROP_EDITING_CANCELED:
if (priv->editing_canceled != g_value_get_boolean (value))
{
priv->editing_canceled = g_value_get_boolean (value);
g_object_notify_by_pspec (object, entry_props[PROP_EDITING_CANCELED]);
}
break ;
case PROP_COMPLETION:
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (g_value_get_object (value)));
G_GNUC_END_IGNORE_DEPRECATIONS
break ;
case PROP_SHOW_EMOJI_ICON:
set_show_emoji_icon (entry, g_value_get_boolean (value));
break ;
case PROP_EXTRA_MENU:
gtk_entry_set_extra_menu (entry, g_value_get_object (value));
break ;
case PROP_MENU_ENTRY_ICON_PRIMARY_TEXT:
gtk_entry_set_menu_entry_icon_text (entry,
GTK_ENTRY_ICON_PRIMARY,
g_value_get_string (value));
break ;
case PROP_MENU_ENTRY_ICON_SECONDARY_TEXT:
gtk_entry_set_menu_entry_icon_text (entry,
GTK_ENTRY_ICON_SECONDARY,
g_value_get_string (value));
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break ;
}
}
static void
gtk_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkEntry *entry = GTK_ENTRY (object);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (gtk_editable_delegate_get_property (object, prop_id, value, pspec))
return ;
switch (prop_id)
{
case PROP_BUFFER:
case PROP_IM_MODULE:
case PROP_MAX_LENGTH:
case PROP_VISIBILITY:
case PROP_INVISIBLE_CHAR:
case PROP_INVISIBLE_CHAR_SET:
case PROP_ACTIVATES_DEFAULT:
case PROP_SCROLL_OFFSET:
case PROP_TRUNCATE_MULTILINE:
case PROP_OVERWRITE_MODE:
case PROP_PLACEHOLDER_TEXT:
case PROP_INPUT_PURPOSE:
case PROP_INPUT_HINTS:
case PROP_ATTRIBUTES:
case PROP_TABS:
case PROP_ENABLE_EMOJI_COMPLETION:
g_object_get_property (G_OBJECT (priv->text), pspec->name, value);
break ;
case PROP_HAS_FRAME:
g_value_set_boolean (value, gtk_entry_get_has_frame (entry));
break ;
case PROP_TEXT_LENGTH:
g_value_set_uint (value, gtk_entry_get_text_length (entry));
break ;
case PROP_PROGRESS_FRACTION:
g_value_set_double (value, gtk_entry_get_progress_fraction (entry));
break ;
case PROP_PROGRESS_PULSE_STEP:
g_value_set_double (value, gtk_entry_get_progress_pulse_step (entry));
break ;
case PROP_PAINTABLE_PRIMARY:
g_value_set_object (value,
gtk_entry_get_icon_paintable (entry,
GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_PAINTABLE_SECONDARY:
g_value_set_object (value,
gtk_entry_get_icon_paintable (entry,
GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_ICON_NAME_PRIMARY:
g_value_set_string (value,
gtk_entry_get_icon_name (entry,
GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_ICON_NAME_SECONDARY:
g_value_set_string (value,
gtk_entry_get_icon_name (entry,
GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_GICON_PRIMARY:
g_value_set_object (value,
gtk_entry_get_icon_gicon (entry,
GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_GICON_SECONDARY:
g_value_set_object (value,
gtk_entry_get_icon_gicon (entry,
GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_STORAGE_TYPE_PRIMARY:
g_value_set_enum (value,
gtk_entry_get_icon_storage_type (entry,
GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_STORAGE_TYPE_SECONDARY:
g_value_set_enum (value,
gtk_entry_get_icon_storage_type (entry,
GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_ACTIVATABLE_PRIMARY:
g_value_set_boolean (value,
gtk_entry_get_icon_activatable (entry, GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_ACTIVATABLE_SECONDARY:
g_value_set_boolean (value,
gtk_entry_get_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_SENSITIVE_PRIMARY:
g_value_set_boolean (value,
gtk_entry_get_icon_sensitive (entry, GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_SENSITIVE_SECONDARY:
g_value_set_boolean (value,
gtk_entry_get_icon_sensitive (entry, GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_TOOLTIP_TEXT_PRIMARY:
g_value_take_string (value,
gtk_entry_get_icon_tooltip_text (entry, GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_TOOLTIP_TEXT_SECONDARY:
g_value_take_string (value,
gtk_entry_get_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_TOOLTIP_MARKUP_PRIMARY:
g_value_take_string (value,
gtk_entry_get_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_TOOLTIP_MARKUP_SECONDARY:
g_value_take_string (value,
gtk_entry_get_icon_tooltip_markup (entry, GTK_ENTRY_ICON_SECONDARY));
break ;
case PROP_EDITING_CANCELED:
g_value_set_boolean (value,
priv->editing_canceled);
break ;
case PROP_COMPLETION:
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_value_set_object (value, G_OBJECT (gtk_entry_get_completion (entry)));
G_GNUC_END_IGNORE_DEPRECATIONS
break ;
case PROP_SHOW_EMOJI_ICON:
g_value_set_boolean (value, priv->show_emoji_icon);
break ;
case PROP_EXTRA_MENU:
g_value_set_object (value, gtk_entry_get_extra_menu (entry));
break ;
case PROP_MENU_ENTRY_ICON_PRIMARY_TEXT:
g_value_set_string (value,
gtk_entry_get_menu_entry_icon_text (entry,
GTK_ENTRY_ICON_PRIMARY));
break ;
case PROP_MENU_ENTRY_ICON_SECONDARY_TEXT:
g_value_set_string (value,
gtk_entry_get_menu_entry_icon_text (entry,
GTK_ENTRY_ICON_SECONDARY));
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break ;
}
}
static void
activate_cb (GtkText *text, GtkEntry *entry)
{
g_signal_emit (entry, signals[ACTIVATE], 0 );
}
static void
notify_cb (GObject *object,
GParamSpec *pspec,
gpointer data)
{
gpointer iface;
gpointer class ;
/* The editable interface properties are already forwarded by the editable delegate setup */
iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)), gtk_editable_get_type ());
class = g_type_class_peek (GTK_TYPE_ENTRY);
if (!g_object_interface_find_property (iface, pspec->name) &&
g_object_class_find_property (class , pspec->name))
g_object_notify (data, pspec->name);
}
static void
connect_text_signals (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_signal_connect (priv->text, "activate" , G_CALLBACK (activate_cb), entry);
g_signal_connect (priv->text, "notify" , G_CALLBACK (notify_cb), entry);
}
static void
disconnect_text_signals (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_signal_handlers_disconnect_by_func (priv->text, activate_cb, entry);
g_signal_handlers_disconnect_by_func (priv->text, notify_cb, entry);
}
static void
catchall_click_press (GtkGestureClick *gesture,
int n_press,
double x,
double y,
gpointer user_data)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
gtk_entry_init (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
GtkGesture *catchall;
priv->text = gtk_text_new ();
gtk_widget_set_parent (priv->text, GTK_WIDGET (entry));
gtk_editable_init_delegate (GTK_EDITABLE (entry));
connect_text_signals (entry);
catchall = gtk_gesture_click_new ();
g_signal_connect (catchall, "pressed" ,
G_CALLBACK (catchall_click_press), entry);
gtk_widget_add_controller (GTK_WIDGET (entry),
GTK_EVENT_CONTROLLER (catchall));
priv->editing_canceled = FALSE ;
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_HAS_POPUP, TRUE ,
-1 );
}
static void
gtk_entry_dispose (GObject *object)
{
GtkEntry *entry = GTK_ENTRY (object);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
gtk_entry_set_icon_from_paintable (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_PRIMARY, NULL);
gtk_entry_set_icon_from_paintable (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
gtk_entry_set_icon_tooltip_markup (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_entry_set_completion (entry, NULL);
G_GNUC_END_IGNORE_DEPRECATIONS
if (priv->text)
{
disconnect_text_signals (entry);
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
}
g_clear_pointer (&priv->text, gtk_widget_unparent);
g_clear_object (&priv->extra_menu);
g_clear_pointer (&priv->menu_entry_icon_primary_text, g_free);
g_clear_pointer (&priv->menu_entry_icon_secondary_text, g_free);
G_OBJECT_CLASS (gtk_entry_parent_class)->dispose (object);
}
static void
gtk_entry_finalize (GObject *object)
{
GtkEntry *entry = GTK_ENTRY (object);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info = NULL;
int i;
for (i = 0 ; i < MAX_ICONS; i++)
{
icon_info = priv->icons[i];
if (icon_info == NULL)
continue ;
g_clear_object (&icon_info->content);
gtk_widget_unparent (icon_info->widget);
g_free (icon_info);
}
g_clear_pointer (&priv->progress_widget, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
}
static void
update_icon_style (GtkWidget *widget,
GtkEntryIconPosition icon_pos)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info = priv->icons[icon_pos];
const char *sides[2 ] = { "left" , "right" };
if (icon_info == NULL)
return ;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
icon_pos = 1 - icon_pos;
gtk_widget_add_css_class (icon_info->widget, sides[icon_pos]);
gtk_widget_remove_css_class (icon_info->widget, sides[1 - icon_pos]);
}
static void
update_node_ordering (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
GtkEntryIconPosition first_icon_pos, second_icon_pos;
if (priv->progress_widget)
gtk_widget_insert_before (priv->progress_widget, GTK_WIDGET (entry), NULL);
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
{
first_icon_pos = GTK_ENTRY_ICON_SECONDARY;
second_icon_pos = GTK_ENTRY_ICON_PRIMARY;
}
else
{
first_icon_pos = GTK_ENTRY_ICON_PRIMARY;
second_icon_pos = GTK_ENTRY_ICON_SECONDARY;
}
icon_info = priv->icons[first_icon_pos];
if (icon_info)
gtk_widget_insert_after (icon_info->widget, GTK_WIDGET (entry), NULL);
icon_info = priv->icons[second_icon_pos];
if (icon_info)
gtk_widget_insert_before (icon_info->widget, GTK_WIDGET (entry), NULL);
}
static GtkEntryIconPosition
get_icon_position_from_controller (GtkEntry *entry,
GtkEventController *controller)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
GtkWidget *widget = gtk_event_controller_get_widget (controller);
if (priv->icons[GTK_ENTRY_ICON_PRIMARY] &&
priv->icons[GTK_ENTRY_ICON_PRIMARY]->widget == widget)
return GTK_ENTRY_ICON_PRIMARY;
else if (priv->icons[GTK_ENTRY_ICON_SECONDARY] &&
priv->icons[GTK_ENTRY_ICON_SECONDARY]->widget == widget)
return GTK_ENTRY_ICON_SECONDARY;
g_assert_not_reached ();
return -1 ;
}
static void
icon_pressed_cb (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
GtkEntryIconPosition pos;
EntryIconInfo *icon_info;
pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture));
icon_info = priv->icons[pos];
if (!icon_info->nonactivatable)
g_signal_emit (entry, signals[ICON_PRESS], 0 , pos);
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
icon_released_cb (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
GtkEntryIconPosition pos;
EntryIconInfo *icon_info;
pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture));
icon_info = priv->icons[pos];
if (!icon_info->nonactivatable)
g_signal_emit (entry, signals[ICON_RELEASE], 0 , pos);
}
static void
icon_drag_update_cb (GtkGestureDrag *gesture,
double offset_x,
double offset_y,
GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
GtkEntryIconPosition pos;
EntryIconInfo *icon_info;
pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture));
icon_info = priv->icons[pos];
if (icon_info->content != NULL &&
gtk_drag_check_threshold_double (icon_info->widget, 0 , 0 , offset_x, offset_y))
{
GdkPaintable *paintable;
GdkSurface *surface;
GdkDevice *device;
GdkDrag *drag;
double start_x, start_y;
icon_info->in_drag = TRUE ;
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (entry)));
device = gtk_gesture_get_device (GTK_GESTURE (gesture));
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
drag = gdk_drag_begin (surface, device, icon_info->content, icon_info->actions, start_x, start_y);
paintable = gtk_widget_paintable_new (icon_info->widget);
gtk_drag_icon_set_from_paintable (drag, paintable, -2 , -2 );
g_object_unref (paintable);
g_object_unref (drag);
}
}
static EntryIconInfo*
construct_icon_info (GtkWidget *widget,
GtkEntryIconPosition icon_pos)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
GtkGesture *drag, *press;
g_return_val_if_fail (priv->icons[icon_pos] == NULL, NULL);
icon_info = g_new0 (EntryIconInfo, 1 );
priv->icons[icon_pos] = icon_info;
icon_info->widget = g_object_new (GTK_TYPE_IMAGE,
"visible" , FALSE ,
NULL);
gtk_widget_set_cursor_from_name (icon_info->widget, "default" );
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
gtk_widget_insert_before (icon_info->widget, widget, priv->text);
else
gtk_widget_insert_after (icon_info->widget, widget, priv->text);
update_icon_style (widget, icon_pos);
update_node_ordering (entry);
press = gtk_gesture_click_new ();
g_signal_connect (press, "pressed" , G_CALLBACK (icon_pressed_cb), entry);
g_signal_connect (press, "released" , G_CALLBACK (icon_released_cb), entry);
gtk_widget_add_controller (icon_info->widget, GTK_EVENT_CONTROLLER (press));
drag = gtk_gesture_drag_new ();
g_signal_connect (drag, "drag-update" ,
G_CALLBACK (icon_drag_update_cb), entry);
gtk_widget_add_controller (icon_info->widget, GTK_EVENT_CONTROLLER (drag));
gtk_gesture_group (press, drag);
return icon_info;
}
static void
gtk_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
int text_min, text_nat;
int i;
gtk_widget_measure (priv->text,
orientation,
for_size,
&text_min, &text_nat,
minimum_baseline, natural_baseline);
*minimum = text_min;
*natural = text_nat;
for (i = 0 ; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
int icon_min, icon_nat;
if (!icon_info)
continue ;
gtk_widget_measure (icon_info->widget,
GTK_ORIENTATION_HORIZONTAL,
-1 , &icon_min, &icon_nat, NULL, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
*minimum += icon_min;
*natural += icon_nat;
}
else
{
*minimum = MAX (*minimum, icon_min);
*natural = MAX (*natural, icon_nat);
}
}
if (priv->progress_widget && gtk_widget_get_visible (priv->progress_widget))
{
int prog_min, prog_nat;
gtk_widget_measure (priv->progress_widget,
orientation,
for_size,
&prog_min, &prog_nat,
NULL, NULL);
*minimum = MAX (*minimum, prog_min);
*natural = MAX (*natural, prog_nat);
}
if (orientation == GTK_ORIENTATION_VERTICAL)
{
if (G_LIKELY (*minimum_baseline >= 0 ))
*minimum_baseline += (*minimum - text_min) / 2 ;
if (G_LIKELY (*natural_baseline >= 0 ))
*natural_baseline += (*natural - text_nat) / 2 ;
}
}
static void
gtk_entry_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
const gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
int i;
GtkAllocation text_alloc;
text_alloc.x = 0 ;
text_alloc.y = 0 ;
text_alloc.width = width;
text_alloc.height = height;
if (gtk_widget_get_valign (widget) != GTK_ALIGN_BASELINE_FILL &&
gtk_widget_get_valign (widget) != GTK_ALIGN_BASELINE_CENTER)
baseline = -1 ;
for (i = 0 ; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
GtkAllocation icon_alloc;
int icon_width;
if (!icon_info)
continue ;
gtk_widget_measure (icon_info->widget,
GTK_ORIENTATION_HORIZONTAL,
-1 ,
NULL, &icon_width,
NULL, NULL);
if ((is_rtl && i == GTK_ENTRY_ICON_PRIMARY) ||
(!is_rtl && i == GTK_ENTRY_ICON_SECONDARY))
icon_alloc.x = width - icon_width;
else
icon_alloc.x = 0 ;
icon_alloc.y = 0 ;
icon_alloc.width = icon_width;
icon_alloc.height = height;
gtk_widget_size_allocate (icon_info->widget, &icon_alloc, baseline);
text_alloc.width -= icon_width;
if ((!is_rtl && i == GTK_ENTRY_ICON_PRIMARY) ||
(is_rtl && i == GTK_ENTRY_ICON_SECONDARY))
text_alloc.x += icon_width;
}
gtk_widget_size_allocate (priv->text, &text_alloc, baseline);
if (priv->progress_widget && gtk_widget_get_visible (priv->progress_widget))
{
GtkAllocation progress_alloc;
int min, nat;
gtk_widget_measure (priv->progress_widget,
GTK_ORIENTATION_VERTICAL,
-1 ,
&min, &nat,
NULL, NULL);
progress_alloc.x = 0 ;
progress_alloc.y = height - nat;
progress_alloc.width = width;
progress_alloc.height = nat;
gtk_widget_size_allocate (priv->progress_widget, &progress_alloc, -1 );
}
/* Do this here instead of gtk_entry_size_allocate() so it works
* inside spinbuttons , which don ' t chain up .
*/
if (gtk_widget_get_realized (widget))
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GtkEntryCompletion *completion;
completion = gtk_entry_get_completion (entry);
if (completion)
_gtk_entry_completion_resize_popup (completion);
G_GNUC_END_IGNORE_DEPRECATIONS
}
}
static void
gtk_entry_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
int i;
/* Draw progress */
if (priv->progress_widget && gtk_widget_get_visible (priv->progress_widget))
gtk_widget_snapshot_child (widget, priv->progress_widget, snapshot);
gtk_widget_snapshot_child (widget, priv->text, snapshot);
/* Draw icons */
for (i = 0 ; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
if (icon_info != NULL)
gtk_widget_snapshot_child (widget, icon_info->widget, snapshot);
}
}
/**
* gtk_entry_grab_focus_without_selecting :
* @ entry : a ` GtkEntry `
*
* Causes @ entry to have keyboard focus .
*
* It behaves like [ method @ Gtk . Widget . grab_focus ] , except that it doesn ' t
* select the contents of the entry . You only want to call this on some
* special entries which the user usually doesn ' t want to replace all text
* in , such as search - as - you - type entries .
*
* Returns : % TRUE if focus is now inside @ self
*/
gboolean
gtk_entry_grab_focus_without_selecting (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
return gtk_text_grab_focus_without_selecting (GTK_TEXT (priv->text));
}
static void
gtk_entry_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GtkEntry *entry = GTK_ENTRY (widget);
update_icon_style (widget, GTK_ENTRY_ICON_PRIMARY);
update_icon_style (widget, GTK_ENTRY_ICON_SECONDARY);
update_node_ordering (entry);
GTK_WIDGET_CLASS (gtk_entry_parent_class)->direction_changed (widget, previous_dir);
}
/* GtkCellEditable method implementations
*/
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
gtk_cell_editable_entry_activated (GtkEntry *entry, gpointer data)
{
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
}
static gboolean
gtk_cell_editable_entry_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (keyval == GDK_KEY_Escape)
{
priv->editing_canceled = TRUE ;
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
return GDK_EVENT_STOP;
}
/* override focus */
if (keyval == GDK_KEY_Up || keyval == GDK_KEY_Down)
{
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
return GDK_EVENT_STOP;
}
return GDK_EVENT_PROPAGATE;
}
static void
gtk_entry_start_editing (GtkCellEditable *cell_editable,
GdkEvent *event)
{
g_signal_connect (cell_editable, "activate" ,
G_CALLBACK (gtk_cell_editable_entry_activated), NULL);
g_signal_connect (gtk_entry_get_key_controller (GTK_ENTRY (cell_editable)),
"key-pressed" ,
G_CALLBACK (gtk_cell_editable_entry_key_pressed),
cell_editable);
}
G_GNUC_END_IGNORE_DEPRECATIONS
/* Internal functions
*/
/**
* 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 .
*/
void
gtk_entry_reset_im_context (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_reset_im_context (GTK_TEXT (priv->text));
}
static void
gtk_entry_clear_icon (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info = priv->icons[icon_pos];
GtkImageType storage_type;
if (icon_info == NULL)
return ;
storage_type = gtk_image_get_storage_type (GTK_IMAGE (icon_info->widget));
if (storage_type == GTK_IMAGE_EMPTY)
return ;
g_object_freeze_notify (G_OBJECT (entry));
switch (storage_type)
{
case GTK_IMAGE_PAINTABLE:
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_PAINTABLE_PRIMARY
: PROP_PAINTABLE_SECONDARY]);
break ;
case GTK_IMAGE_ICON_NAME:
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_ICON_NAME_PRIMARY
: PROP_ICON_NAME_SECONDARY]);
break ;
case GTK_IMAGE_GICON:
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_GICON_PRIMARY
: PROP_GICON_SECONDARY]);
break ;
case GTK_IMAGE_EMPTY:
default :
g_assert_not_reached ();
break ;
}
gtk_image_clear (GTK_IMAGE (icon_info->widget));
gtk_widget_set_visible (icon_info->widget, FALSE );
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_STORAGE_TYPE_PRIMARY
: PROP_STORAGE_TYPE_SECONDARY]);
g_object_thaw_notify (G_OBJECT (entry));
}
/* Public API
*/
/**
* gtk_entry_new :
*
* Creates a new entry .
*
* Returns : a new ` GtkEntry ` .
*/
GtkWidget*
gtk_entry_new (void )
{
return g_object_new (GTK_TYPE_ENTRY, NULL);
}
/**
* gtk_entry_new_with_buffer :
* @ buffer : The buffer to use for the new ` GtkEntry ` .
*
* Creates a new entry with the specified text buffer .
*
* Returns : a new ` GtkEntry `
*/
GtkWidget*
gtk_entry_new_with_buffer (GtkEntryBuffer *buffer)
{
g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), NULL);
return g_object_new (GTK_TYPE_ENTRY, "buffer" , buffer, NULL);
}
static GtkEntryBuffer*
get_buffer (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
return gtk_text_get_buffer (GTK_TEXT (priv->text));
}
/**
* gtk_entry_get_buffer :
* @ entry : a ` GtkEntry `
*
* Get the ` GtkEntryBuffer ` object which holds the text for
* this widget .
*
* Returns : ( transfer none ) : A ` GtkEntryBuffer ` object .
*/
GtkEntryBuffer*
gtk_entry_get_buffer (GtkEntry *entry)
{
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
return get_buffer (entry);
}
/**
* gtk_entry_set_buffer :
* @ entry : a ` GtkEntry `
* @ buffer : a ` GtkEntryBuffer `
*
* Set the ` GtkEntryBuffer ` object which holds the text for
* this widget .
*/
void
gtk_entry_set_buffer (GtkEntry *entry,
GtkEntryBuffer *buffer)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_buffer (GTK_TEXT (priv->text), buffer);
}
/**
* gtk_entry_set_visibility :
* @ entry : a ` GtkEntry `
* @ visible : % TRUE if the contents of the entry are displayed as plaintext
*
* Sets whether the contents of the entry are visible or not .
*
* When visibility is set to % FALSE , characters are displayed
* as the invisible char , and will also appear that way when
* the text in the entry widget is copied elsewhere .
*
* By default , GTK picks the best invisible character available
* in the current font , but it can be changed with
* [ method @ Gtk . Entry . set_invisible_char ] .
*
* Note that you probably want to set [ property @ Gtk . Entry : input - purpose ]
* to % GTK_INPUT_PURPOSE_PASSWORD or % GTK_INPUT_PURPOSE_PIN to
* inform input methods about the purpose of this entry ,
* in addition to setting visibility to % FALSE .
*/
void
gtk_entry_set_visibility (GtkEntry *entry,
gboolean visible)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_visibility (GTK_TEXT (priv->text), visible);
}
/**
* gtk_entry_get_visibility :
* @ entry : a ` GtkEntry `
*
* Retrieves whether the text in @ entry is visible .
*
* See [ method @ Gtk . Entry . set_visibility ] .
*
* Returns : % TRUE if the text is currently visible
*/
gboolean
gtk_entry_get_visibility (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
return gtk_text_get_visibility (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_invisible_char :
* @ entry : a ` GtkEntry `
* @ ch : a Unicode character
*
* Sets the character to use in place of the actual text
* in “ password mode ” .
*
* See [ method @ Gtk . Entry . set_visibility ] for how to enable
* “ password mode ” .
*
* By default , GTK picks the best invisible char available in
* the current font . If you set the invisible char to 0 , then
* the user will get no feedback at all ; there will be no text
* on the screen as they type .
*/
void
gtk_entry_set_invisible_char (GtkEntry *entry,
gunichar ch)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_invisible_char (GTK_TEXT (priv->text), ch);
}
/**
* gtk_entry_get_invisible_char :
* @ entry : a ` GtkEntry `
*
* Retrieves the character displayed in place of the actual text
* in “ password mode ” .
*
* Returns : the current invisible char , or 0 , if the entry does not
* show invisible text at all .
*/
gunichar
gtk_entry_get_invisible_char (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 );
return gtk_text_get_invisible_char (GTK_TEXT (priv->text));
}
/**
* gtk_entry_unset_invisible_char :
* @ entry : a ` GtkEntry `
*
* Unsets the invisible char , so that the default invisible char
* is used again . See [ method @ Gtk . Entry . set_invisible_char ] .
*/
void
gtk_entry_unset_invisible_char (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_unset_invisible_char (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_overwrite_mode :
* @ entry : a ` GtkEntry `
* @ overwrite : new value
*
* Sets whether the text is overwritten when typing in the ` GtkEntry ` .
*/
void
gtk_entry_set_overwrite_mode (GtkEntry *entry,
gboolean overwrite)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_overwrite_mode (GTK_TEXT (priv->text), overwrite);
}
/**
* gtk_entry_get_overwrite_mode :
* @ entry : a ` GtkEntry `
*
* Gets whether the ` GtkEntry ` is in overwrite mode .
*
* Returns : whether the text is overwritten when typing .
*/
gboolean
gtk_entry_get_overwrite_mode (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
return gtk_text_get_overwrite_mode (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_max_length :
* @ entry : a ` GtkEntry `
* @ 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 .
*
* Sets the maximum allowed length of the contents of the widget .
*
* If the current contents are longer than the given length , then
* they will be truncated to fit . The length is in characters .
*
* This is equivalent to getting @ entry ' s ` GtkEntryBuffer ` and
* calling [ method @ Gtk . EntryBuffer . set_max_length ] on it .
*/
void
gtk_entry_set_max_length (GtkEntry *entry,
int max)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_max_length (GTK_TEXT (priv->text), max);
}
/**
* gtk_entry_get_max_length :
* @ entry : a ` GtkEntry `
*
* Retrieves the maximum allowed length of the text in @ entry .
*
* See [ method @ Gtk . Entry . set_max_length ] .
*
* Returns : the maximum allowed number of characters
* in ` GtkEntry ` , or 0 if there is no maximum .
*/
int
gtk_entry_get_max_length (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 );
return gtk_text_get_max_length (GTK_TEXT (priv->text));
}
/**
* gtk_entry_get_text_length :
* @ entry : a ` GtkEntry `
*
* Retrieves the current length of the text in @ entry .
*
* This is equivalent to getting @ entry ' s ` GtkEntryBuffer `
* and calling [ method @ Gtk . EntryBuffer . get_length ] on it .
*
* Returns : the current number of characters
* in ` GtkEntry ` , or 0 if there are none .
*/
guint16
gtk_entry_get_text_length (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 );
return gtk_text_get_text_length (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_activates_default :
* @ entry : a ` GtkEntry `
* @ setting : % TRUE to activate window ’ s default widget on Enter keypress
*
* Sets whether pressing Enter in the @ entry will activate the default
* widget for the window containing the entry .
*
* This usually means that the dialog containing the entry will be closed ,
* since the default widget is usually one of the dialog buttons .
*/
void
gtk_entry_set_activates_default (GtkEntry *entry,
gboolean setting)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_activates_default (GTK_TEXT (priv->text), setting);
}
/**
* gtk_entry_get_activates_default :
* @ entry : a ` GtkEntry `
*
* Retrieves the value set by gtk_entry_set_activates_default ( ) .
*
* Returns : % TRUE if the entry will activate the default widget
*/
gboolean
gtk_entry_get_activates_default (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
return gtk_text_get_activates_default (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_has_frame :
* @ entry : a ` GtkEntry `
* @ setting : new value
*
* Sets whether the entry has a beveled frame around it .
*/
void
gtk_entry_set_has_frame (GtkEntry *entry,
gboolean setting)
{
g_return_if_fail (GTK_IS_ENTRY (entry));
setting = (setting != FALSE );
if (setting == gtk_entry_get_has_frame (entry))
return ;
if (setting)
gtk_widget_remove_css_class (GTK_WIDGET (entry), "flat" );
else
gtk_widget_add_css_class (GTK_WIDGET (entry), "flat" );
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_HAS_FRAME]);
}
/**
* gtk_entry_get_has_frame :
* @ entry : a ` GtkEntry `
*
* Gets the value set by gtk_entry_set_has_frame ( ) .
*
* Returns : whether the entry has a beveled frame
*/
gboolean
gtk_entry_get_has_frame (GtkEntry *entry)
{
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
return !gtk_widget_has_css_class (GTK_WIDGET (entry), "flat" );
}
/**
* gtk_entry_set_alignment :
* @ entry : a ` GtkEntry `
* @ xalign : The horizontal alignment , from 0 ( left ) to 1 ( right ) .
* Reversed for RTL layouts
*
* Sets the alignment for the contents of the entry .
*
* This controls the horizontal positioning of the contents when
* the displayed text is shorter than the width of the entry .
*
* See also : [ property @ Gtk . Editable : xalign ]
*/
void
gtk_entry_set_alignment (GtkEntry *entry,
float xalign)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_editable_set_alignment (GTK_EDITABLE (priv->text), xalign);
}
/**
* gtk_entry_get_alignment :
* @ entry : a ` GtkEntry `
*
* Gets the value set by gtk_entry_set_alignment ( ) .
*
* See also : [ property @ Gtk . Editable : xalign ]
*
* Returns : the alignment
*/
float
gtk_entry_get_alignment (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 .0 );
return gtk_editable_get_alignment (GTK_EDITABLE (priv->text));
}
/**
* gtk_entry_set_icon_from_paintable :
* @ entry : a ` GtkEntry `
* @ icon_pos : Icon position
* @ paintable : ( nullable ) : A ` GdkPaintable `
*
* Sets the icon shown in the specified position using a ` GdkPaintable ` .
*
* If @ paintable is % NULL , no icon will be shown in the specified position .
*/
void
gtk_entry_set_icon_from_paintable (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GdkPaintable *paintable)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
g_object_freeze_notify (G_OBJECT (entry));
if (paintable)
{
EntryIconInfo *icon_info;
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_object_ref (paintable);
gtk_image_set_from_paintable (GTK_IMAGE (icon_info->widget), paintable);
gtk_widget_set_visible (icon_info->widget, TRUE );
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PAINTABLE_PRIMARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_PRIMARY]);
}
else
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PAINTABLE_SECONDARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_SECONDARY]);
}
g_object_unref (paintable);
}
else
gtk_entry_clear_icon (entry, icon_pos);
if (gtk_widget_get_visible (GTK_WIDGET (entry)))
gtk_widget_queue_resize (GTK_WIDGET (entry));
g_object_thaw_notify (G_OBJECT (entry));
}
/**
* gtk_entry_set_icon_from_icon_name :
* @ entry : A ` GtkEntry `
* @ icon_pos : The position at which to set the icon
* @ icon_name : ( nullable ) : An icon name
*
* Sets the icon shown in the entry at the specified position
* from the current icon theme .
*
* If the icon name isn ’ t known , a “ broken image ” icon will be
* displayed instead .
*
* If @ icon_name is % NULL , no icon will be shown in the
* specified position .
*/
void
gtk_entry_set_icon_from_icon_name (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
const char *icon_name)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_object_freeze_notify (G_OBJECT (entry));
if (icon_name != NULL)
{
gtk_image_set_from_icon_name (GTK_IMAGE (icon_info->widget), icon_name);
gtk_widget_set_visible (icon_info->widget, TRUE );
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_ICON_NAME_PRIMARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_PRIMARY]);
}
else
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_ICON_NAME_SECONDARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_SECONDARY]);
}
}
else
gtk_entry_clear_icon (entry, icon_pos);
if (gtk_widget_get_visible (GTK_WIDGET (entry)))
gtk_widget_queue_resize (GTK_WIDGET (entry));
g_object_thaw_notify (G_OBJECT (entry));
}
/**
* gtk_entry_set_icon_from_gicon :
* @ entry : A ` GtkEntry `
* @ icon_pos : The position at which to set the icon
* @ icon : ( nullable ) : The icon to set
*
* Sets the icon shown in the entry at the specified position
* from the current icon theme .
*
* If the icon isn ’ t known , a “ broken image ” icon will be
* displayed instead .
*
* If @ icon is % NULL , no icon will be shown in the
* specified position .
*/
void
gtk_entry_set_icon_from_gicon (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GIcon *icon)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_object_freeze_notify (G_OBJECT (entry));
if (icon)
{
gtk_image_set_from_gicon (GTK_IMAGE (icon_info->widget), icon);
gtk_widget_set_visible (icon_info->widget, TRUE );
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_GICON_PRIMARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_PRIMARY]);
}
else
{
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_GICON_SECONDARY]);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_STORAGE_TYPE_SECONDARY]);
}
}
else
gtk_entry_clear_icon (entry, icon_pos);
if (gtk_widget_get_visible (GTK_WIDGET (entry)))
gtk_widget_queue_resize (GTK_WIDGET (entry));
g_object_thaw_notify (G_OBJECT (entry));
}
/**
* gtk_entry_set_icon_activatable :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
* @ activatable : % TRUE if the icon should be activatable
*
* Sets whether the icon is activatable .
*/
void
gtk_entry_set_icon_activatable (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
gboolean activatable)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
activatable = activatable != FALSE ;
if (icon_info->nonactivatable != !activatable)
{
icon_info->nonactivatable = !activatable;
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_ACTIVATABLE_PRIMARY
: PROP_ACTIVATABLE_SECONDARY]);
}
update_extra_menu (entry);
}
/**
* gtk_entry_get_icon_activatable :
* @ entry : a ` GtkEntry `
* @ icon_pos : Icon position
*
* Returns whether the icon is activatable .
*
* Returns : % TRUE if the icon is activatable .
*/
gboolean
gtk_entry_get_icon_activatable (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), FALSE );
icon_info = priv->icons[icon_pos];
return (!icon_info || !icon_info->nonactivatable);
}
/**
* gtk_entry_get_icon_paintable :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
*
* Retrieves the ` GdkPaintable ` used for the icon .
*
* If no ` GdkPaintable ` was used for the icon , % NULL is returned .
*
* Returns : ( transfer none ) ( nullable ) : A ` GdkPaintable `
* if no icon is set for this position or the icon set is not
* a ` GdkPaintable ` .
*/
GdkPaintable *
gtk_entry_get_icon_paintable (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return NULL;
return gtk_image_get_paintable (GTK_IMAGE (icon_info->widget));
}
/**
* gtk_entry_get_icon_gicon :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
*
* Retrieves the ` GIcon ` used for the icon .
*
* % NULL will be returned if there is no icon or if the icon was
* set by some other method ( e . g . , by ` GdkPaintable ` or icon name ) .
*
* Returns : ( transfer none ) ( nullable ) : A ` GIcon `
*/
GIcon *
gtk_entry_get_icon_gicon (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return NULL;
return gtk_image_get_gicon (GTK_IMAGE (icon_info->widget));
}
/**
* gtk_entry_get_icon_name :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
*
* Retrieves the icon name used for the icon .
*
* % NULL is returned if there is no icon or if the icon was set
* by some other method ( e . g . , by ` GdkPaintable ` or gicon ) .
*
* Returns : ( nullable ) : An icon name
*/
const char *
gtk_entry_get_icon_name (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return NULL;
return gtk_image_get_icon_name (GTK_IMAGE (icon_info->widget));
}
/**
* gtk_entry_set_icon_sensitive :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
* @ sensitive : Specifies whether the icon should appear
* sensitive or insensitive
*
* Sets the sensitivity for the specified icon .
*/
void
gtk_entry_set_icon_sensitive (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
gboolean sensitive)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
if (gtk_widget_get_sensitive (icon_info->widget) != sensitive)
{
gtk_widget_set_sensitive (icon_info->widget, sensitive);
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_SENSITIVE_PRIMARY
: PROP_SENSITIVE_SECONDARY]);
}
update_extra_menu (entry);
}
/**
* gtk_entry_get_icon_sensitive :
* @ entry : a ` GtkEntry `
* @ icon_pos : Icon position
*
* Returns whether the icon appears sensitive or insensitive .
*
* Returns : % TRUE if the icon is sensitive .
*/
gboolean
gtk_entry_get_icon_sensitive (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), TRUE );
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), TRUE );
icon_info = priv->icons[icon_pos];
if (!icon_info)
return TRUE ; /* Default of the property */
return gtk_widget_get_sensitive (icon_info->widget);
}
/**
* gtk_entry_get_icon_storage_type :
* @ entry : a ` GtkEntry `
* @ icon_pos : Icon position
*
* Gets the type of representation being used by the icon
* to store image data .
*
* If the icon has no image data , the return value will
* be % GTK_IMAGE_EMPTY .
*
* Returns : image representation being used
*/
GtkImageType
gtk_entry_get_icon_storage_type (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_IMAGE_EMPTY);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), GTK_IMAGE_EMPTY);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return GTK_IMAGE_EMPTY;
return gtk_image_get_storage_type (GTK_IMAGE (icon_info->widget));
}
/**
* gtk_entry_get_icon_at_pos :
* @ entry : a ` GtkEntry `
* @ x : the x coordinate of the position to find , relative to @ entry
* @ y : the y coordinate of the position to find , relative to @ entry
*
* Finds the icon at the given position and return its index .
*
* The position ’ s coordinates are relative to the @ entry ’ s
* top left corner . If @ x , @ y doesn ’ t lie inside an icon ,
* - 1 is returned . This function is intended for use in a
* [ signal @ Gtk . Widget : : query - tooltip ] signal handler .
*
* Returns : the index of the icon at the given position , or - 1
*/
int
gtk_entry_get_icon_at_pos (GtkEntry *entry,
int x,
int y)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
guint i;
g_return_val_if_fail (GTK_IS_ENTRY (entry), -1 );
for (i = 0 ; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
graphene_point_t p;
if (icon_info == NULL)
continue ;
if (!gtk_widget_compute_point (GTK_WIDGET (entry), icon_info->widget,
&GRAPHENE_POINT_INIT (x, y), &p))
continue ;
if (gtk_widget_contains (icon_info->widget, p.x, p.y))
return i;
}
return -1 ;
}
/**
* gtk_entry_set_icon_drag_source :
* @ entry : a ` GtkEntry `
* @ icon_pos : icon position
* @ provider : a ` GdkContentProvider `
* @ actions : a bitmask of the allowed drag actions
*
* Sets up the icon at the given position as drag source .
*
* This makes it so that GTK will start a drag
* operation when the user clicks and drags the icon .
*/
void
gtk_entry_set_icon_drag_source (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GdkContentProvider *provider,
GdkDragAction actions)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_set_object (&icon_info->content, provider);
icon_info->actions = actions;
}
/**
* gtk_entry_get_current_icon_drag_source :
* @ entry : a ` GtkEntry `
*
* Returns the index of the icon which is the source of the
* current DND operation , or - 1 .
*
* Returns : index of the icon which is the source of the
* current DND operation , or - 1 .
*/
int
gtk_entry_get_current_icon_drag_source (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info = NULL;
int i;
g_return_val_if_fail (GTK_IS_ENTRY (entry), -1 );
for (i = 0 ; i < MAX_ICONS; i++)
{
if ((icon_info = priv->icons[i]))
{
if (icon_info->in_drag)
return i;
}
}
return -1 ;
}
/**
* gtk_entry_get_icon_area :
* @ entry : A ` GtkEntry `
* @ icon_pos : Icon position
* @ icon_area : ( out ) : Return location for the icon ’ s area
*
* Gets the area where entry ’ s icon at @ icon_pos is drawn .
*
* This function is useful when drawing something to the
* entry in a draw callback .
*
* If the entry is not realized or has no icon at the given
* position , @ icon_area is filled with zeros . Otherwise ,
* @ icon_area will be filled with the icon ' s allocation ,
* relative to @ entry ' s allocation .
*/
void
gtk_entry_get_icon_area (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GdkRectangle *icon_area)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
graphene_rect_t r;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (icon_area != NULL);
icon_info = priv->icons[icon_pos];
if (icon_info &&
gtk_widget_compute_bounds (icon_info->widget, GTK_WIDGET (entry), &r))
{
*icon_area = (GdkRectangle){
floorf (r.origin.x),
floorf (r.origin.y),
ceilf (r.size.width),
ceilf (r.size.height),
};
}
else
{
icon_area->x = 0 ;
icon_area->y = 0 ;
icon_area->width = 0 ;
icon_area->height = 0 ;
}
}
static void
ensure_has_tooltip (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
const char *text = gtk_widget_get_tooltip_text (GTK_WIDGET (entry));
gboolean has_tooltip = text != NULL;
if (!has_tooltip)
{
int i;
for (i = 0 ; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
if (icon_info != NULL && icon_info->tooltip != NULL)
{
has_tooltip = TRUE ;
break ;
}
}
}
gtk_widget_set_has_tooltip (GTK_WIDGET (entry), has_tooltip);
}
/**
* gtk_entry_get_icon_tooltip_text :
* @ entry : a ` GtkEntry `
* @ icon_pos : the icon position
*
* Gets the contents of the tooltip on the icon at the specified
* position in @ entry .
*
* Returns : ( nullable ) ( transfer full ) : the tooltip text
*/
char *
gtk_entry_get_icon_tooltip_text (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
char *text = NULL;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return NULL;
if (icon_info->tooltip &&
!pango_parse_markup (icon_info->tooltip, -1 , 0 , NULL, &text, NULL, NULL))
g_assert (NULL == text); /* text should still be NULL in case of markup errors */
return text;
}
/**
* gtk_entry_set_icon_tooltip_text :
* @ entry : a ` GtkEntry `
* @ icon_pos : the icon position
* @ tooltip : ( nullable ) : the contents of the tooltip for the icon
*
* Sets @ tooltip as the contents of the tooltip for the icon
* at the specified position .
*
* Use % NULL for @ tooltip to remove an existing tooltip .
*
* See also [ method @ Gtk . Widget . set_tooltip_text ] and
* [ method @ Gtk . Entry . set_icon_tooltip_markup ] .
*
* If you unset the widget tooltip via
* [ method @ Gtk . Widget . set_tooltip_text ] or
* [ method @ Gtk . Widget . set_tooltip_markup ] , this sets
* [ property @ Gtk . Widget : has - tooltip ] to % FALSE , which suppresses
* icon tooltips too . You can resolve this by then calling
* [ method @ Gtk . Widget . set_has_tooltip ] to set
* [ property @ Gtk . Widget : has - tooltip ] back to % TRUE , or
* setting at least one non - empty tooltip on any icon
* achieves the same result .
*/
void
gtk_entry_set_icon_tooltip_text (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
const char *tooltip)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_free (icon_info->tooltip);
/* Treat an empty string as a NULL string,
* because an empty string would be useless for a tooltip :
*/
if (tooltip && tooltip[0 ] == '\0' )
tooltip = NULL;
icon_info->tooltip = tooltip ? g_markup_escape_text (tooltip, -1 ) : NULL;
ensure_has_tooltip (entry);
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_TOOLTIP_TEXT_PRIMARY
: PROP_TOOLTIP_TEXT_SECONDARY]);
}
/**
* gtk_entry_get_icon_tooltip_markup :
* @ entry : a ` GtkEntry `
* @ icon_pos : the icon position
*
* Gets the contents of the tooltip on the icon at the specified
* position in @ entry .
*
* Returns : ( nullable ) ( transfer full ) : the tooltip text
*/
char *
gtk_entry_get_icon_tooltip_markup (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL);
icon_info = priv->icons[icon_pos];
if (!icon_info)
return NULL;
return g_strdup (icon_info->tooltip);
}
/**
* gtk_entry_set_icon_tooltip_markup :
* @ entry : a ` GtkEntry `
* @ icon_pos : the icon position
* @ tooltip : ( nullable ) : the contents of the tooltip for the icon
*
* Sets @ tooltip as the contents of the tooltip for the icon at
* the specified position .
*
* @ tooltip is assumed to be marked up with Pango Markup .
*
* Use % NULL for @ tooltip to remove an existing tooltip .
*
* See also [ method @ Gtk . Widget . set_tooltip_markup ] and
* [ method @ Gtk . Entry . set_icon_tooltip_text ] .
*/
void
gtk_entry_set_icon_tooltip_markup (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
const char *tooltip)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (IS_VALID_ICON_POSITION (icon_pos));
if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
g_free (icon_info->tooltip);
/* Treat an empty string as a NULL string,
* because an empty string would be useless for a tooltip :
*/
if (tooltip && tooltip[0 ] == '\0' )
tooltip = NULL;
icon_info->tooltip = g_strdup (tooltip);
ensure_has_tooltip (entry);
g_object_notify_by_pspec (G_OBJECT (entry),
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
? PROP_TOOLTIP_MARKUP_PRIMARY
: PROP_TOOLTIP_MARKUP_SECONDARY]);
}
static gboolean
gtk_entry_query_tooltip (GtkWidget *widget,
int x,
int y,
gboolean keyboard_tip,
GtkTooltip *tooltip)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
int icon_pos;
if (!keyboard_tip)
{
icon_pos = gtk_entry_get_icon_at_pos (entry, x, y);
if (icon_pos != -1 )
{
if ((icon_info = priv->icons[icon_pos]) != NULL)
{
if (icon_info->tooltip)
{
gtk_tooltip_set_markup (tooltip, icon_info->tooltip);
return TRUE ;
}
return FALSE ;
}
}
}
return GTK_WIDGET_CLASS (gtk_entry_parent_class)->query_tooltip (widget,
x, y,
keyboard_tip,
tooltip);
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* gtk_entry_set_completion :
* @ entry : A ` GtkEntry `
* @ completion : ( nullable ) : The ` GtkEntryCompletion `
*
* Sets @ completion to be the auxiliary completion object
* to use with @ entry .
*
* All further configuration of the completion mechanism is
* done on @ completion using the ` GtkEntryCompletion ` API .
* Completion is disabled if @ completion is set to % NULL .
*
* Deprecated : 4 . 10 : GtkEntryCompletion will be removed in GTK 5 .
*/
void
gtk_entry_set_completion (GtkEntry *entry,
GtkEntryCompletion *completion)
{
GtkEntryCompletion *old;
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (!completion || GTK_IS_ENTRY_COMPLETION (completion));
old = gtk_entry_get_completion (entry);
if (old == completion)
return ;
if (old)
{
_gtk_entry_completion_disconnect (old);
g_object_unref (old);
}
if (!completion)
{
g_object_set_qdata (G_OBJECT (entry), quark_entry_completion, NULL);
return ;
}
/* hook into the entry */
g_object_ref (completion);
_gtk_entry_completion_connect (completion, entry);
g_object_set_qdata (G_OBJECT (entry), quark_entry_completion, completion);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_COMPLETION]);
}
/**
* gtk_entry_get_completion :
* @ entry : A ` GtkEntry `
*
* Returns the auxiliary completion object currently
* in use by @ entry .
*
* Returns : ( nullable ) ( transfer none ) : The auxiliary
* completion object currently in use by @ entry
*
* Deprecated : 4 . 10 : GtkEntryCompletion will be removed in GTK 5 .
*/
GtkEntryCompletion *
gtk_entry_get_completion (GtkEntry *entry)
{
GtkEntryCompletion *completion;
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
completion = GTK_ENTRY_COMPLETION (g_object_get_qdata (G_OBJECT (entry), quark_entry_completion));
return completion;
}
G_GNUC_END_IGNORE_DEPRECATIONS
static void
gtk_entry_ensure_progress_widget (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (priv->progress_widget)
return ;
priv->progress_widget = g_object_new (GTK_TYPE_PROGRESS_BAR,
"css-name" , "progress" ,
NULL);
gtk_widget_set_can_target (priv->progress_widget, FALSE );
gtk_widget_set_parent (priv->progress_widget, GTK_WIDGET (entry));
update_node_ordering (entry);
}
/**
* gtk_entry_set_progress_fraction :
* @ entry : a ` GtkEntry `
* @ fraction : fraction of the task that ’ s been completed
*
* Causes the entry ’ s progress indicator to “ fill in ” the given
* fraction of the bar .
*
* The fraction should be between 0 . 0 and 1 . 0 , inclusive .
*/
void
gtk_entry_set_progress_fraction (GtkEntry *entry,
double fraction)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
double old_fraction;
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_entry_ensure_progress_widget (entry);
old_fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (priv->progress_widget));
fraction = CLAMP (fraction, 0 .0 , 1 .0 );
if (fraction != old_fraction)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress_widget), fraction);
gtk_widget_set_visible (priv->progress_widget, fraction > 0 );
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PROGRESS_FRACTION]);
}
}
/**
* gtk_entry_get_progress_fraction :
* @ entry : a ` GtkEntry `
*
* Returns the current fraction of the task that ’ s been completed .
*
* See [ method @ Gtk . Entry . set_progress_fraction ] .
*
* Returns : a fraction from 0 . 0 to 1 . 0
*/
double
gtk_entry_get_progress_fraction (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 .0 );
if (priv->progress_widget)
return gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (priv->progress_widget));
return 0 .0 ;
}
/**
* gtk_entry_set_progress_pulse_step :
* @ entry : a ` GtkEntry `
* @ fraction : fraction between 0 . 0 and 1 . 0
*
* Sets the fraction of total entry width to move the progress
* bouncing block for each pulse .
*
* Use [ method @ Gtk . Entry . progress_pulse ] to pulse
* the progress .
*/
void
gtk_entry_set_progress_pulse_step (GtkEntry *entry,
double fraction)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
fraction = CLAMP (fraction, 0 .0 , 1 .0 );
gtk_entry_ensure_progress_widget (entry);
if (fraction != gtk_progress_bar_get_pulse_step (GTK_PROGRESS_BAR (priv->progress_widget)))
{
gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (priv->progress_widget), fraction);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PROGRESS_PULSE_STEP]);
}
}
/**
* gtk_entry_get_progress_pulse_step :
* @ entry : a ` GtkEntry `
*
* Retrieves the pulse step set with
* gtk_entry_set_progress_pulse_step ( ) .
*
* Returns : a fraction from 0 . 0 to 1 . 0
*/
double
gtk_entry_get_progress_pulse_step (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0 .0 );
if (priv->progress_widget)
return gtk_progress_bar_get_pulse_step (GTK_PROGRESS_BAR (priv->progress_widget));
return 0 .0 ;
}
/**
* gtk_entry_progress_pulse :
* @ entry : a ` GtkEntry `
*
* Indicates that some progress is made , but you don ’ t
* know how much .
*
* Causes the entry ’ s progress indicator to enter “ activity
* mode ” , where a block bounces back and forth . Each call to
* gtk_entry_progress_pulse ( ) causes the block to move by a
* little bit ( the amount of movement per pulse is determined
* by [ method @ Gtk . Entry . set_progress_pulse_step ] ) .
*/
void
gtk_entry_progress_pulse (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
if (priv->progress_widget)
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progress_widget));
}
/**
* gtk_entry_set_placeholder_text :
* @ entry : a ` GtkEntry `
* @ text : ( nullable ) : a string to be displayed when @ entry is empty and unfocused
*
* Sets text to be displayed in @ entry when it is empty .
*
* This can be used to give a visual hint of the expected
* contents of the ` GtkEntry ` .
*/
void
gtk_entry_set_placeholder_text (GtkEntry *entry,
const char *text)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_placeholder_text (GTK_TEXT (priv->text), text);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER, text,
-1 );
}
/**
* gtk_entry_get_placeholder_text :
* @ entry : a ` GtkEntry `
*
* Retrieves the text that will be displayed when @ entry
* is empty and unfocused
*
* Returns : ( nullable ) ( transfer none ) : a pointer to the
* placeholder text as a string . This string points to
* internally allocated storage in the widget and must
* not be freed , modified or stored . If no placeholder
* text has been set , % NULL will be returned .
*/
const char *
gtk_entry_get_placeholder_text (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
return gtk_text_get_placeholder_text (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_input_purpose :
* @ entry : a ` GtkEntry `
* @ purpose : the purpose
*
* Sets the input purpose which can be used by input methods
* to adjust their behavior .
*/
void
gtk_entry_set_input_purpose (GtkEntry *entry,
GtkInputPurpose purpose)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_input_purpose (GTK_TEXT (priv->text), purpose);
}
/**
* gtk_entry_get_input_purpose :
* @ entry : a ` GtkEntry `
*
* Gets the input purpose of the ` GtkEntry ` .
*
* Returns : the input purpose
*/
GtkInputPurpose
gtk_entry_get_input_purpose (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
return gtk_text_get_input_purpose (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_input_hints :
* @ entry : a ` GtkEntry `
* @ hints : the hints
*
* Set additional hints which allow input methods to
* fine - tune their behavior .
*/
void
gtk_entry_set_input_hints (GtkEntry *entry,
GtkInputHints hints)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_input_hints (GTK_TEXT (priv->text), hints);
}
/**
* gtk_entry_get_input_hints :
* @ entry : a ` GtkEntry `
*
* Gets the input hints of this ` GtkEntry ` .
*
* Returns : the input hints
*/
GtkInputHints
gtk_entry_get_input_hints (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
return gtk_text_get_input_hints (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_attributes :
* @ entry : a ` GtkEntry `
* @ attrs : a ` PangoAttrList `
*
* Sets a ` PangoAttrList ` .
*
* The attributes in the list are applied to the entry text .
*
* Since the attributes will be applied to text that changes
* as the user types , it makes most sense to use attributes
* with unlimited extent .
*/
void
gtk_entry_set_attributes (GtkEntry *entry,
PangoAttrList *attrs)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_attributes (GTK_TEXT (priv->text), attrs);
}
/**
* gtk_entry_get_attributes :
* @ entry : a ` GtkEntry `
*
* Gets the attribute list of the ` GtkEntry ` .
*
* See [ method @ Gtk . Entry . set_attributes ] .
*
* Returns : ( transfer none ) ( nullable ) : the attribute list
*/
PangoAttrList *
gtk_entry_get_attributes (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
return gtk_text_get_attributes (GTK_TEXT (priv->text));
}
/**
* gtk_entry_set_tabs :
* @ entry : a ` GtkEntry `
* @ tabs : ( nullable ) : a ` PangoTabArray `
*
* Sets a ` PangoTabArray ` .
*
* The tabstops in the array are applied to the entry text .
*/
void
gtk_entry_set_tabs (GtkEntry *entry,
PangoTabArray *tabs)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_text_set_tabs (GTK_TEXT (priv->text), tabs);
}
/**
* gtk_entry_get_tabs :
* @ entry : a ` GtkEntry `
*
* Gets the tabstops of the ` GtkEntry ` .
*
* See [ method @ Gtk . Entry . set_tabs ] .
*
* Returns : ( nullable ) ( transfer none ) : the tabstops
*/
PangoTabArray *
gtk_entry_get_tabs (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
return gtk_text_get_tabs (GTK_TEXT (priv->text));
}
static void
pick_emoji (GtkEntry *entry,
int icon,
GdkEvent *event,
gpointer data)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (gtk_widget_get_ancestor (GTK_WIDGET (entry), GTK_TYPE_EMOJI_CHOOSER) != NULL)
return ;
if (icon == GTK_ENTRY_ICON_SECONDARY)
g_signal_emit_by_name (priv->text, "insert-emoji" );
}
static void
set_show_emoji_icon (GtkEntry *entry,
gboolean value)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
if (priv->show_emoji_icon == value)
return ;
priv->show_emoji_icon = value;
if (priv->show_emoji_icon)
{
gtk_entry_set_icon_from_icon_name (entry,
GTK_ENTRY_ICON_SECONDARY,
"face-smile-symbolic" );
gtk_entry_set_icon_sensitive (entry,
GTK_ENTRY_ICON_SECONDARY,
TRUE );
gtk_entry_set_icon_activatable (entry,
GTK_ENTRY_ICON_SECONDARY,
TRUE );
gtk_entry_set_icon_tooltip_text (entry,
GTK_ENTRY_ICON_SECONDARY,
_("Insert Emoji" ));
g_signal_connect (entry, "icon-press" , G_CALLBACK (pick_emoji), NULL);
}
else
{
g_signal_handlers_disconnect_by_func (entry, pick_emoji, NULL);
gtk_entry_set_icon_from_icon_name (entry,
GTK_ENTRY_ICON_SECONDARY,
NULL);
gtk_entry_set_icon_tooltip_text (entry,
GTK_ENTRY_ICON_SECONDARY,
NULL);
}
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_SHOW_EMOJI_ICON]);
gtk_widget_queue_resize (GTK_WIDGET (entry));
}
GtkEventController *
gtk_entry_get_key_controller (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
return gtk_text_get_key_controller (GTK_TEXT (priv->text));
}
GtkText *
gtk_entry_get_text_widget (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
return GTK_TEXT (priv->text);
}
/**
* gtk_entry_get_menu_entry_icon_text :
* @ entry : a ` GtkEntry `
* @ icon_pos : either @ GTK_ENTRY_ICON_PRIMARY or @ GTK_ENTRY_ICON_SECONDARY
*
* Gets the text that will be used in the context menu of the ` GtkEntry `
* when the specified icon is activatable . Selecting this item in the menu
* results , from all aspects , the same than clicking on the specified icon .
* This greatly simplifies making accessible applications , because the icons
* aren ' t focusable when using keyboard navigation . This is why Gtk recommends
* to add the same action to the context menu .
*
* Returns : ( nullable ) ( transfer none ) : the text that will be used in the menu item ,
* or NULL if no menu item is desired .
*
* Since : 4 . 20
*/
const char *
gtk_entry_get_menu_entry_icon_text (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
switch (icon_pos)
{
case GTK_ENTRY_ICON_PRIMARY:
return priv->menu_entry_icon_primary_text;
case GTK_ENTRY_ICON_SECONDARY:
return priv->menu_entry_icon_secondary_text;
default :
g_assert_not_reached ();
return NULL;
}
}
/**
* gtk_entry_set_menu_entry_icon_text :
* @ entry : a ` GtkEntry `
* @ icon_pos : either @ GTK_ENTRY_ICON_PRIMARY or @ GTK_ENTRY_ICON_SECONDARY
* @ text : the text used for the menu item in the context menu , or NULL to not add a menu item .
*
* Sets the text that will be used in the context menu of the ` GtkEntry `
* when the specified icon is activatable . Selecting this item in the menu
* results , from all aspects , the same than clicking on the specified icon .
* This greatly simplifies making accessible applications , because the icons
* aren ' t focusable when using keyboard navigation . This is why Gtk recommends
* to add the same action to the context menu .
*
* Since : 4 . 20
*/
void
gtk_entry_set_menu_entry_icon_text (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
const gchar *text)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
char **text_p = NULL;
guint prop_id = 0 ;
g_return_if_fail (GTK_IS_ENTRY (entry));
switch (icon_pos)
{
case GTK_ENTRY_ICON_PRIMARY:
text_p = &priv->menu_entry_icon_primary_text;
prop_id = PROP_MENU_ENTRY_ICON_PRIMARY_TEXT;
break ;
case GTK_ENTRY_ICON_SECONDARY:
text_p = &priv->menu_entry_icon_secondary_text;
prop_id = PROP_MENU_ENTRY_ICON_SECONDARY_TEXT;
break ;
default :
g_assert_not_reached ();
return ;
}
if (!g_set_str (text_p, text))
return ;
update_extra_menu (entry);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[prop_id]);
}
static GMenuItem *
create_icon_menu_entry (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
const gchar *menu_entry_text)
{
GMenuItem *item;
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
const gchar *action_name = (icon_pos == GTK_ENTRY_ICON_PRIMARY)
? "misc.menu_entry_icon_primary"
: "misc.menu_entry_icon_secondary" ;
EntryIconInfo *icon_info = priv->icons[icon_pos];
if (icon_info == NULL)
return NULL;
if (icon_info->nonactivatable)
return NULL;
if (menu_entry_text == NULL)
return NULL;
item = g_menu_item_new (menu_entry_text, action_name);
gtk_widget_action_set_enabled (GTK_WIDGET (entry), action_name,
gtk_widget_get_sensitive (icon_info->widget));
return item;
}
static void
update_extra_menu (GtkEntry *entry)
{
GtkJoinedMenu *joined;
GMenu *menu;
GMenu *section;
GMenuItem *item;
gboolean has_icon_entries = FALSE ;
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
joined = gtk_joined_menu_new ();
menu = g_menu_new ();
section = g_menu_new ();
item = create_icon_menu_entry (entry,
GTK_ENTRY_ICON_PRIMARY,
priv->menu_entry_icon_primary_text);
if (item != NULL)
{
has_icon_entries = TRUE ;
g_menu_append_item (section, item);
g_clear_object (&item);
}
item = create_icon_menu_entry (entry,
GTK_ENTRY_ICON_SECONDARY,
priv->menu_entry_icon_secondary_text);
if (item != NULL)
{
has_icon_entries = TRUE ;
g_menu_append_item (section, item);
g_clear_object (&item);
}
if (has_icon_entries)
{
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
gtk_joined_menu_append_menu (joined, G_MENU_MODEL (menu));
if (priv->extra_menu != NULL)
gtk_joined_menu_append_menu (joined, G_MENU_MODEL (priv->extra_menu));
gtk_text_set_extra_menu (GTK_TEXT (priv->text), G_MENU_MODEL (joined));
}
else
{
gtk_text_set_extra_menu (GTK_TEXT (priv->text), priv->extra_menu);
}
g_object_unref (joined);
g_object_unref (menu);
g_object_unref (section);
}
/**
* gtk_entry_set_extra_menu :
* @ entry : a ` GtkEntry `
* @ model : ( nullable ) : a ` GMenuModel `
*
* Sets a menu model to add when constructing
* the context menu for @ entry .
*/
void
gtk_entry_set_extra_menu (GtkEntry *entry,
GMenuModel *model)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_if_fail (GTK_IS_ENTRY (entry));
g_clear_object (&priv->extra_menu);
priv->extra_menu = g_object_ref (model);
update_extra_menu (entry);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_EXTRA_MENU]);
}
/**
* gtk_entry_get_extra_menu :
* @ entry : a ` GtkEntry `
*
* Gets the menu model set with gtk_entry_set_extra_menu ( ) .
*
* Returns : ( transfer none ) ( nullable ) : the menu model
*/
GMenuModel *
gtk_entry_get_extra_menu (GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
return priv->extra_menu;
}
/*< private >
* gtk_entry_activate_icon :
* @ entry : a ` GtkEntry `
* @ pos : the icon position
*
* Activates an icon .
*
* This causes the [ signal @ Gtk . Entry : : icon - press ] and
* [ signal @ Gtk . Entry : : icon - release ] signals to be emitted
* on the @ entry icon at the given @ pos , if the icon is
* set and activatable .
*
* Returns : % TRUE if the signal was emitted
*/
gboolean
gtk_entry_activate_icon (GtkEntry *entry,
GtkEntryIconPosition pos)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
EntryIconInfo *icon_info;
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE );
icon_info = priv->icons[pos];
if (icon_info != NULL &&
gtk_image_get_storage_type (GTK_IMAGE (icon_info->widget)) != GTK_IMAGE_EMPTY &&
!icon_info->nonactivatable)
{
g_signal_emit (entry, signals[ICON_PRESS], 0 , pos);
g_signal_emit (entry, signals[ICON_RELEASE], 0 , pos);
return TRUE ;
}
return FALSE ;
}
Messung V0.5 in Prozent C=98 H=97 G=97
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.134Bemerkung:
(vorverarbeitet am 2026-07-03)
¤
*Bot Zugriff