| 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 | } |