File: | ctk/ctksearchentry.c |
Warning: | line 464, column 47 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* CTK - The GIMP Toolkit |
2 | * Copyright (C) 2012 Red Hat, Inc. |
3 | * |
4 | * Authors: |
5 | * - Bastien Nocera <bnocera@redhat.com> |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
19 | */ |
20 | |
21 | /* |
22 | * Modified by the CTK+ Team and others 2012. See the AUTHORS |
23 | * file for a list of people on the CTK+ Team. See the ChangeLog |
24 | * files for a list of changes. These files are distributed with |
25 | * CTK+ at ftp://ftp.ctk.org/pub/ctk/. |
26 | */ |
27 | |
28 | #include "config.h" |
29 | |
30 | #include "ctksearchentry.h" |
31 | |
32 | #include "ctkaccessible.h" |
33 | #include "ctkbindings.h" |
34 | #include "ctkintl.h" |
35 | #include "ctkmarshalers.h" |
36 | #include "ctkstylecontext.h" |
37 | |
38 | /** |
39 | * SECTION:ctksearchentry |
40 | * @Short_description: An entry which shows a search icon |
41 | * @Title: CtkSearchEntry |
42 | * |
43 | * #CtkSearchEntry is a subclass of #CtkEntry that has been |
44 | * tailored for use as a search entry. |
45 | * |
46 | * It will show an inactive symbolic “find” icon when the search |
47 | * entry is empty, and a symbolic “clear” icon when there is text. |
48 | * Clicking on the “clear” icon will empty the search entry. |
49 | * |
50 | * Note that the search/clear icon is shown using a secondary |
51 | * icon, and thus does not work if you are using the secondary |
52 | * icon position for some other purpose. |
53 | * |
54 | * To make filtering appear more reactive, it is a good idea to |
55 | * not react to every change in the entry text immediately, but |
56 | * only after a short delay. To support this, #CtkSearchEntry |
57 | * emits the #CtkSearchEntry::search-changed signal which can |
58 | * be used instead of the #CtkEditable::changed signal. |
59 | * |
60 | * The #CtkSearchEntry::previous-match, #CtkSearchEntry::next-match |
61 | * and #CtkSearchEntry::stop-search signals can be used to implement |
62 | * moving between search results and ending the search. |
63 | * |
64 | * Often, CtkSearchEntry will be fed events by means of being |
65 | * placed inside a #CtkSearchBar. If that is not the case, |
66 | * you can use ctk_search_entry_handle_event() to pass events. |
67 | * |
68 | * Since: 3.6 |
69 | */ |
70 | |
71 | enum { |
72 | SEARCH_CHANGED, |
73 | NEXT_MATCH, |
74 | PREVIOUS_MATCH, |
75 | STOP_SEARCH, |
76 | LAST_SIGNAL |
77 | }; |
78 | |
79 | static guint signals[LAST_SIGNAL] = { 0 }; |
80 | |
81 | typedef struct { |
82 | guint delayed_changed_id; |
83 | gboolean content_changed; |
84 | gboolean search_stopped; |
85 | } CtkSearchEntryPrivate; |
86 | |
87 | static void ctk_search_entry_icon_release (CtkEntry *entry, |
88 | CtkEntryIconPosition icon_pos); |
89 | static void ctk_search_entry_changed (CtkEditable *editable); |
90 | static void ctk_search_entry_editable_init (CtkEditableInterface *iface); |
91 | |
92 | static CtkEditableInterface *parent_editable_iface; |
93 | |
94 | G_DEFINE_TYPE_WITH_CODE (CtkSearchEntry, ctk_search_entry, CTK_TYPE_ENTRY,static void ctk_search_entry_init (CtkSearchEntry *self); static void ctk_search_entry_class_init (CtkSearchEntryClass *klass ); static GType ctk_search_entry_get_type_once (void); static gpointer ctk_search_entry_parent_class = ((void*)0); static gint CtkSearchEntry_private_offset; static void ctk_search_entry_class_intern_init (gpointer klass) { ctk_search_entry_parent_class = g_type_class_peek_parent (klass); if (CtkSearchEntry_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkSearchEntry_private_offset); ctk_search_entry_class_init ((CtkSearchEntryClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_search_entry_get_instance_private (CtkSearchEntry *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkSearchEntry_private_offset)))); } GType ctk_search_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_search_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_search_entry_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple ((ctk_entry_get_type ()), g_intern_static_string ("CtkSearchEntry" ), sizeof (CtkSearchEntryClass), (GClassInitFunc)(void (*)(void )) ctk_search_entry_class_intern_init, sizeof (CtkSearchEntry ), (GInstanceInitFunc)(void (*)(void)) ctk_search_entry_init, (GTypeFlags) 0); { {{ CtkSearchEntry_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkSearchEntryPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_search_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
95 | G_ADD_PRIVATE (CtkSearchEntry)static void ctk_search_entry_init (CtkSearchEntry *self); static void ctk_search_entry_class_init (CtkSearchEntryClass *klass ); static GType ctk_search_entry_get_type_once (void); static gpointer ctk_search_entry_parent_class = ((void*)0); static gint CtkSearchEntry_private_offset; static void ctk_search_entry_class_intern_init (gpointer klass) { ctk_search_entry_parent_class = g_type_class_peek_parent (klass); if (CtkSearchEntry_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkSearchEntry_private_offset); ctk_search_entry_class_init ((CtkSearchEntryClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_search_entry_get_instance_private (CtkSearchEntry *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkSearchEntry_private_offset)))); } GType ctk_search_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_search_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_search_entry_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple ((ctk_entry_get_type ()), g_intern_static_string ("CtkSearchEntry" ), sizeof (CtkSearchEntryClass), (GClassInitFunc)(void (*)(void )) ctk_search_entry_class_intern_init, sizeof (CtkSearchEntry ), (GInstanceInitFunc)(void (*)(void)) ctk_search_entry_init, (GTypeFlags) 0); { {{ CtkSearchEntry_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkSearchEntryPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_search_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
96 | G_IMPLEMENT_INTERFACE (CTK_TYPE_EDITABLE,static void ctk_search_entry_init (CtkSearchEntry *self); static void ctk_search_entry_class_init (CtkSearchEntryClass *klass ); static GType ctk_search_entry_get_type_once (void); static gpointer ctk_search_entry_parent_class = ((void*)0); static gint CtkSearchEntry_private_offset; static void ctk_search_entry_class_intern_init (gpointer klass) { ctk_search_entry_parent_class = g_type_class_peek_parent (klass); if (CtkSearchEntry_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkSearchEntry_private_offset); ctk_search_entry_class_init ((CtkSearchEntryClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_search_entry_get_instance_private (CtkSearchEntry *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkSearchEntry_private_offset)))); } GType ctk_search_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_search_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_search_entry_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple ((ctk_entry_get_type ()), g_intern_static_string ("CtkSearchEntry" ), sizeof (CtkSearchEntryClass), (GClassInitFunc)(void (*)(void )) ctk_search_entry_class_intern_init, sizeof (CtkSearchEntry ), (GInstanceInitFunc)(void (*)(void)) ctk_search_entry_init, (GTypeFlags) 0); { {{ CtkSearchEntry_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkSearchEntryPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_search_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
97 | ctk_search_entry_editable_init))static void ctk_search_entry_init (CtkSearchEntry *self); static void ctk_search_entry_class_init (CtkSearchEntryClass *klass ); static GType ctk_search_entry_get_type_once (void); static gpointer ctk_search_entry_parent_class = ((void*)0); static gint CtkSearchEntry_private_offset; static void ctk_search_entry_class_intern_init (gpointer klass) { ctk_search_entry_parent_class = g_type_class_peek_parent (klass); if (CtkSearchEntry_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkSearchEntry_private_offset); ctk_search_entry_class_init ((CtkSearchEntryClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_search_entry_get_instance_private (CtkSearchEntry *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkSearchEntry_private_offset)))); } GType ctk_search_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_search_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_search_entry_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple ((ctk_entry_get_type ()), g_intern_static_string ("CtkSearchEntry" ), sizeof (CtkSearchEntryClass), (GClassInitFunc)(void (*)(void )) ctk_search_entry_class_intern_init, sizeof (CtkSearchEntry ), (GInstanceInitFunc)(void (*)(void)) ctk_search_entry_init, (GTypeFlags) 0); { {{ CtkSearchEntry_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkSearchEntryPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_search_entry_editable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_editable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
98 | |
99 | /* 150 mseconds of delay */ |
100 | #define DELAYED_TIMEOUT_ID150 150 |
101 | |
102 | /* This widget got created without a private structure, meaning |
103 | * that we cannot now have one without breaking ABI */ |
104 | #define GET_PRIV(e)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (e))) ((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (e))) |
105 | |
106 | static void |
107 | ctk_search_entry_preedit_changed (CtkEntry *entry, |
108 | const gchar *preedit G_GNUC_UNUSED__attribute__ ((__unused__))) |
109 | { |
110 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
111 | |
112 | priv->content_changed = TRUE(!(0)); |
113 | } |
114 | |
115 | static void |
116 | ctk_search_entry_notify (GObject *object, |
117 | GParamSpec *pspec) |
118 | { |
119 | CtkSearchEntryPrivate *priv = GET_PRIV (object)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (object))); |
120 | |
121 | if (strcmp (pspec->name, "text") == 0) |
122 | priv->content_changed = TRUE(!(0)); |
123 | |
124 | if (G_OBJECT_CLASS (ctk_search_entry_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_search_entry_parent_class)), (((GType) ((20) << (2))))))))->notify) |
125 | G_OBJECT_CLASS (ctk_search_entry_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_search_entry_parent_class)), (((GType) ((20) << (2))))))))->notify (object, pspec); |
126 | } |
127 | |
128 | static void |
129 | ctk_search_entry_finalize (GObject *object) |
130 | { |
131 | CtkSearchEntryPrivate *priv = GET_PRIV (object)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (object))); |
132 | |
133 | if (priv->delayed_changed_id > 0) |
134 | g_source_remove (priv->delayed_changed_id); |
135 | |
136 | G_OBJECT_CLASS (ctk_search_entry_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_search_entry_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); |
137 | } |
138 | |
139 | static void |
140 | ctk_search_entry_stop_search (CtkSearchEntry *entry) |
141 | { |
142 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
143 | |
144 | priv->search_stopped = TRUE(!(0)); |
145 | } |
146 | |
147 | static void |
148 | ctk_search_entry_class_init (CtkSearchEntryClass *klass) |
149 | { |
150 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); |
151 | CtkBindingSet *binding_set; |
152 | |
153 | object_class->finalize = ctk_search_entry_finalize; |
154 | object_class->notify = ctk_search_entry_notify; |
155 | |
156 | klass->stop_search = ctk_search_entry_stop_search; |
157 | |
158 | g_signal_override_class_handler ("icon-release", |
159 | CTK_TYPE_SEARCH_ENTRY(ctk_search_entry_get_type ()), |
160 | G_CALLBACK (ctk_search_entry_icon_release)((GCallback) (ctk_search_entry_icon_release))); |
161 | |
162 | g_signal_override_class_handler ("preedit-changed", |
163 | CTK_TYPE_SEARCH_ENTRY(ctk_search_entry_get_type ()), |
164 | G_CALLBACK (ctk_search_entry_preedit_changed)((GCallback) (ctk_search_entry_preedit_changed))); |
165 | |
166 | /** |
167 | * CtkSearchEntry::search-changed: |
168 | * @entry: the entry on which the signal was emitted |
169 | * |
170 | * The #CtkSearchEntry::search-changed signal is emitted with a short |
171 | * delay of 150 milliseconds after the last change to the entry text. |
172 | * |
173 | * Since: 3.10 |
174 | */ |
175 | signals[SEARCH_CHANGED] = |
176 | g_signal_new (I_("search-changed")g_intern_static_string ("search-changed"), |
177 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
178 | G_SIGNAL_RUN_LAST, |
179 | G_STRUCT_OFFSET (CtkSearchEntryClass, search_changed)((glong) __builtin_offsetof(CtkSearchEntryClass, search_changed )), |
180 | NULL((void*)0), NULL((void*)0), |
181 | NULL((void*)0), |
182 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
183 | |
184 | /** |
185 | * CtkSearchEntry::next-match: |
186 | * @entry: the entry on which the signal was emitted |
187 | * |
188 | * The ::next-match signal is a [keybinding signal][CtkBindingSignal] |
189 | * which gets emitted when the user initiates a move to the next match |
190 | * for the current search string. |
191 | * |
192 | * Applications should connect to it, to implement moving between |
193 | * matches. |
194 | * |
195 | * The default bindings for this signal is Ctrl-g. |
196 | * |
197 | * Since: 3.16 |
198 | */ |
199 | signals[NEXT_MATCH] = |
200 | g_signal_new (I_("next-match")g_intern_static_string ("next-match"), |
201 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
202 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
203 | G_STRUCT_OFFSET (CtkSearchEntryClass, next_match)((glong) __builtin_offsetof(CtkSearchEntryClass, next_match)), |
204 | NULL((void*)0), NULL((void*)0), |
205 | NULL((void*)0), |
206 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
207 | |
208 | /** |
209 | * CtkSearchEntry::previous-match: |
210 | * @entry: the entry on which the signal was emitted |
211 | * |
212 | * The ::previous-match signal is a [keybinding signal][CtkBindingSignal] |
213 | * which gets emitted when the user initiates a move to the previous match |
214 | * for the current search string. |
215 | * |
216 | * Applications should connect to it, to implement moving between |
217 | * matches. |
218 | * |
219 | * The default bindings for this signal is Ctrl-Shift-g. |
220 | * |
221 | * Since: 3.16 |
222 | */ |
223 | signals[PREVIOUS_MATCH] = |
224 | g_signal_new (I_("previous-match")g_intern_static_string ("previous-match"), |
225 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
226 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
227 | G_STRUCT_OFFSET (CtkSearchEntryClass, previous_match)((glong) __builtin_offsetof(CtkSearchEntryClass, previous_match )), |
228 | NULL((void*)0), NULL((void*)0), |
229 | NULL((void*)0), |
230 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
231 | |
232 | /** |
233 | * CtkSearchEntry::stop-search: |
234 | * @entry: the entry on which the signal was emitted |
235 | * |
236 | * The ::stop-search signal is a [keybinding signal][CtkBindingSignal] |
237 | * which gets emitted when the user stops a search via keyboard input. |
238 | * |
239 | * Applications should connect to it, to implement hiding the search |
240 | * entry in this case. |
241 | * |
242 | * The default bindings for this signal is Escape. |
243 | * |
244 | * Since: 3.16 |
245 | */ |
246 | signals[STOP_SEARCH] = |
247 | g_signal_new (I_("stop-search")g_intern_static_string ("stop-search"), |
248 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
249 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
250 | G_STRUCT_OFFSET (CtkSearchEntryClass, stop_search)((glong) __builtin_offsetof(CtkSearchEntryClass, stop_search) ), |
251 | NULL((void*)0), NULL((void*)0), |
252 | NULL((void*)0), |
253 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
254 | |
255 | binding_set = ctk_binding_set_by_class (klass); |
256 | |
257 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_g0x067, CDK_CONTROL_MASK, |
258 | "next-match", 0); |
259 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_g0x067, CDK_SHIFT_MASK | CDK_CONTROL_MASK, |
260 | "previous-match", 0); |
261 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Escape0xff1b, 0, |
262 | "stop-search", 0); |
263 | } |
264 | |
265 | static void |
266 | ctk_search_entry_editable_init (CtkEditableInterface *iface) |
267 | { |
268 | parent_editable_iface = g_type_interface_peek_parent (iface); |
269 | iface->do_insert_text = parent_editable_iface->do_insert_text; |
270 | iface->do_delete_text = parent_editable_iface->do_delete_text; |
271 | iface->insert_text = parent_editable_iface->insert_text; |
272 | iface->delete_text = parent_editable_iface->delete_text; |
273 | iface->get_chars = parent_editable_iface->get_chars; |
274 | iface->set_selection_bounds = parent_editable_iface->set_selection_bounds; |
275 | iface->get_selection_bounds = parent_editable_iface->get_selection_bounds; |
276 | iface->set_position = parent_editable_iface->set_position; |
277 | iface->get_position = parent_editable_iface->get_position; |
278 | iface->changed = ctk_search_entry_changed; |
279 | } |
280 | |
281 | static void |
282 | ctk_search_entry_icon_release (CtkEntry *entry, |
283 | CtkEntryIconPosition icon_pos) |
284 | { |
285 | if (icon_pos == CTK_ENTRY_ICON_SECONDARY) |
286 | ctk_entry_set_text (entry, ""); |
287 | } |
288 | |
289 | static gboolean |
290 | ctk_search_entry_changed_timeout_cb (gpointer user_data) |
291 | { |
292 | CtkSearchEntry *entry = user_data; |
293 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
294 | |
295 | g_signal_emit (entry, signals[SEARCH_CHANGED], 0); |
296 | priv->delayed_changed_id = 0; |
297 | |
298 | return G_SOURCE_REMOVE(0); |
299 | } |
300 | |
301 | static void |
302 | reset_timeout (CtkSearchEntry *entry) |
303 | { |
304 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
305 | |
306 | if (priv->delayed_changed_id > 0) |
307 | g_source_remove (priv->delayed_changed_id); |
308 | priv->delayed_changed_id = g_timeout_add (DELAYED_TIMEOUT_ID150, |
309 | ctk_search_entry_changed_timeout_cb, |
310 | entry); |
311 | g_source_set_name_by_id (priv->delayed_changed_id, "[ctk+] ctk_search_entry_changed_timeout_cb"); |
312 | } |
313 | |
314 | static void |
315 | ctk_search_entry_changed (CtkEditable *editable) |
316 | { |
317 | CtkSearchEntry *entry = CTK_SEARCH_ENTRY (editable)((((CtkSearchEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((editable)), ((ctk_search_entry_get_type ())))))); |
318 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
319 | const char *str, *icon_name; |
320 | gboolean cleared; |
321 | |
322 | /* Update the icons first */ |
323 | str = ctk_entry_get_text (CTK_ENTRY (entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_entry_get_type ()))))))); |
324 | |
325 | if (str == NULL((void*)0) || *str == '\0') |
326 | { |
327 | icon_name = NULL((void*)0); |
328 | cleared = TRUE(!(0)); |
329 | } |
330 | else |
331 | { |
332 | icon_name = "edit-clear-symbolic"; |
333 | cleared = FALSE(0); |
334 | } |
335 | |
336 | g_object_set (entry, |
337 | "secondary-icon-name", icon_name, |
338 | "secondary-icon-activatable", !cleared, |
339 | "secondary-icon-sensitive", !cleared, |
340 | NULL((void*)0)); |
341 | |
342 | if (cleared) |
343 | { |
344 | if (priv->delayed_changed_id > 0) |
345 | { |
346 | g_source_remove (priv->delayed_changed_id); |
347 | priv->delayed_changed_id = 0; |
348 | } |
349 | g_signal_emit (entry, signals[SEARCH_CHANGED], 0); |
350 | } |
351 | else |
352 | { |
353 | /* Queue up the timeout */ |
354 | reset_timeout (entry); |
355 | } |
356 | } |
357 | |
358 | static void |
359 | ctk_search_entry_init (CtkSearchEntry *entry) |
360 | { |
361 | AtkObject *atk_obj; |
362 | |
363 | g_object_set (entry, |
364 | "primary-icon-name", "edit-find-symbolic", |
365 | "primary-icon-activatable", FALSE(0), |
366 | "primary-icon-sensitive", FALSE(0), |
367 | NULL((void*)0)); |
368 | |
369 | atk_obj = ctk_widget_get_accessible (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ()))))))); |
370 | if (CTK_IS_ACCESSIBLE (atk_obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (atk_obj)); GType __t = ((ctk_accessible_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
371 | atk_object_set_name (atk_obj, _("Search")((char *) g_dgettext ("ctk30", "Search"))); |
372 | |
373 | ctk_style_context_add_class (ctk_widget_get_style_context (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ()))))))), "search"); |
374 | } |
375 | |
376 | /** |
377 | * ctk_search_entry_new: |
378 | * |
379 | * Creates a #CtkSearchEntry, with a find icon when the search field is |
380 | * empty, and a clear icon when it isn't. |
381 | * |
382 | * Returns: a new #CtkSearchEntry |
383 | * |
384 | * Since: 3.6 |
385 | */ |
386 | CtkWidget * |
387 | ctk_search_entry_new (void) |
388 | { |
389 | return CTK_WIDGET (g_object_new (CTK_TYPE_SEARCH_ENTRY, NULL))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_new ((ctk_search_entry_get_type ()), ((void*)0) ))), ((ctk_widget_get_type ())))))); |
390 | } |
391 | |
392 | gboolean |
393 | ctk_search_entry_is_keynav_event (CdkEvent *event) |
394 | { |
395 | CdkModifierType state = 0; |
396 | guint keyval; |
397 | |
398 | if (!cdk_event_get_keyval (event, &keyval)) |
399 | return FALSE(0); |
400 | |
401 | cdk_event_get_state (event, &state); |
402 | |
403 | if (keyval == CDK_KEY_Tab0xff09 || keyval == CDK_KEY_KP_Tab0xff89 || |
404 | keyval == CDK_KEY_Up0xff52 || keyval == CDK_KEY_KP_Up0xff97 || |
405 | keyval == CDK_KEY_Down0xff54 || keyval == CDK_KEY_KP_Down0xff99 || |
406 | keyval == CDK_KEY_Left0xff51 || keyval == CDK_KEY_KP_Left0xff96 || |
407 | keyval == CDK_KEY_Right0xff53 || keyval == CDK_KEY_KP_Right0xff98 || |
408 | keyval == CDK_KEY_Home0xff50 || keyval == CDK_KEY_KP_Home0xff95 || |
409 | keyval == CDK_KEY_End0xff57 || keyval == CDK_KEY_KP_End0xff9c || |
410 | keyval == CDK_KEY_Page_Up0xff55 || keyval == CDK_KEY_KP_Page_Up0xff9a || |
411 | keyval == CDK_KEY_Page_Down0xff56 || keyval == CDK_KEY_KP_Page_Down0xff9b || |
412 | ((state & (CDK_CONTROL_MASK | CDK_MOD1_MASK)) != 0)) |
413 | return TRUE(!(0)); |
414 | |
415 | /* Other navigation events should get automatically |
416 | * ignored as they will not change the content of the entry |
417 | */ |
418 | return FALSE(0); |
419 | } |
420 | |
421 | /** |
422 | * ctk_search_entry_handle_event: |
423 | * @entry: a #CtkSearchEntry |
424 | * @event: a key event |
425 | * |
426 | * This function should be called when the top-level window |
427 | * which contains the search entry received a key event. If |
428 | * the entry is part of a #CtkSearchBar, it is preferable |
429 | * to call ctk_search_bar_handle_event() instead, which will |
430 | * reveal the entry in addition to passing the event to this |
431 | * function. |
432 | * |
433 | * If the key event is handled by the search entry and starts |
434 | * or continues a search, %CDK_EVENT_STOP will be returned. |
435 | * The caller should ensure that the entry is shown in this |
436 | * case, and not propagate the event further. |
437 | * |
438 | * Returns: %CDK_EVENT_STOP if the key press event resulted |
439 | * in a search beginning or continuing, %CDK_EVENT_PROPAGATE |
440 | * otherwise. |
441 | * |
442 | * Since: 3.16 |
443 | */ |
444 | gboolean |
445 | ctk_search_entry_handle_event (CtkSearchEntry *entry, |
446 | CdkEvent *event) |
447 | { |
448 | CtkSearchEntryPrivate *priv = GET_PRIV (entry)((CtkSearchEntryPrivate *) ctk_search_entry_get_instance_private ((CtkSearchEntry *) (entry))); |
449 | gboolean handled; |
450 | |
451 | if (!ctk_widget_get_realized (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ())))))))) |
452 | ctk_widget_realize (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ()))))))); |
453 | |
454 | if (ctk_search_entry_is_keynav_event (event) || |
455 | event->key.keyval == CDK_KEY_space0x020 || |
456 | event->key.keyval == CDK_KEY_Menu0xff67) |
457 | return CDK_EVENT_PROPAGATE((0)); |
458 | |
459 | priv->content_changed = FALSE(0); |
460 | priv->search_stopped = FALSE(0); |
461 | |
462 | handled = ctk_widget_event (CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ())))))), event); |
463 | |
464 | return handled && priv->content_changed && !priv->search_stopped ? CDK_EVENT_STOP((!(0))) : CDK_EVENT_PROPAGATE((0)); |
This statement is never executed | |
465 | } |