File: | ctk/ctkentrycompletion.c |
Warning: | line 1877, column 30 Value stored to 'priv' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* ctkentrycompletion.c |
2 | * Copyright (C) 2003 Kristian Rietveld <kris@gtk.org> |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Library General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Library General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Library General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | /** |
19 | * SECTION:ctkentrycompletion |
20 | * @Short_description: Completion functionality for CtkEntry |
21 | * @Title: CtkEntryCompletion |
22 | * |
23 | * #CtkEntryCompletion is an auxiliary object to be used in conjunction with |
24 | * #CtkEntry to provide the completion functionality. It implements the |
25 | * #CtkCellLayout interface, to allow the user to add extra cells to the |
26 | * #CtkTreeView with completion matches. |
27 | * |
28 | * “Completion functionality” means that when the user modifies the text |
29 | * in the entry, #CtkEntryCompletion checks which rows in the model match |
30 | * the current content of the entry, and displays a list of matches. |
31 | * By default, the matching is done by comparing the entry text |
32 | * case-insensitively against the text column of the model (see |
33 | * ctk_entry_completion_set_text_column()), but this can be overridden |
34 | * with a custom match function (see ctk_entry_completion_set_match_func()). |
35 | * |
36 | * When the user selects a completion, the content of the entry is |
37 | * updated. By default, the content of the entry is replaced by the |
38 | * text column of the model, but this can be overridden by connecting |
39 | * to the #CtkEntryCompletion::match-selected signal and updating the |
40 | * entry in the signal handler. Note that you should return %TRUE from |
41 | * the signal handler to suppress the default behaviour. |
42 | * |
43 | * To add completion functionality to an entry, use ctk_entry_set_completion(). |
44 | * |
45 | * In addition to regular completion matches, which will be inserted into the |
46 | * entry when they are selected, #CtkEntryCompletion also allows to display |
47 | * “actions” in the popup window. Their appearance is similar to menuitems, |
48 | * to differentiate them clearly from completion strings. When an action is |
49 | * selected, the #CtkEntryCompletion::action-activated signal is emitted. |
50 | * |
51 | * CtkEntryCompletion uses a #CtkTreeModelFilter model to represent the |
52 | * subset of the entire model that is currently matching. While the |
53 | * CtkEntryCompletion signals #CtkEntryCompletion::match-selected and |
54 | * #CtkEntryCompletion::cursor-on-match take the original model and an |
55 | * iter pointing to that model as arguments, other callbacks and signals |
56 | * (such as #CtkCellLayoutDataFuncs or #CtkCellArea::apply-attributes) |
57 | * will generally take the filter model as argument. As long as you are |
58 | * only calling ctk_tree_model_get(), this will make no difference to |
59 | * you. If for some reason, you need the original model, use |
60 | * ctk_tree_model_filter_get_model(). Don’t forget to use |
61 | * ctk_tree_model_filter_convert_iter_to_child_iter() to obtain a |
62 | * matching iter. |
63 | */ |
64 | |
65 | #include "config.h" |
66 | |
67 | #include "ctkentrycompletion.h" |
68 | |
69 | #include "ctkentryprivate.h" |
70 | #include "ctkcelllayout.h" |
71 | #include "ctkcellareabox.h" |
72 | |
73 | #include "ctkintl.h" |
74 | #include "ctkcellrenderertext.h" |
75 | #include "ctkframe.h" |
76 | #include "ctktreeselection.h" |
77 | #include "ctktreeview.h" |
78 | #include "ctkscrolledwindow.h" |
79 | #include "ctksizerequest.h" |
80 | #include "ctkbox.h" |
81 | #include "ctkwindow.h" |
82 | #include "ctkwindowgroup.h" |
83 | #include "ctkentry.h" |
84 | #include "ctkmain.h" |
85 | #include "ctkmarshalers.h" |
86 | |
87 | #include "ctkprivate.h" |
88 | #include "ctkwindowprivate.h" |
89 | |
90 | #include <string.h> |
91 | |
92 | #define PAGE_STEP14 14 |
93 | #define COMPLETION_TIMEOUT100 100 |
94 | |
95 | /* signals */ |
96 | enum |
97 | { |
98 | INSERT_PREFIX, |
99 | MATCH_SELECTED, |
100 | ACTION_ACTIVATED, |
101 | CURSOR_ON_MATCH, |
102 | NO_MATCHES, |
103 | LAST_SIGNAL |
104 | }; |
105 | |
106 | /* properties */ |
107 | enum |
108 | { |
109 | PROP_0, |
110 | PROP_MODEL, |
111 | PROP_MINIMUM_KEY_LENGTH, |
112 | PROP_TEXT_COLUMN, |
113 | PROP_INLINE_COMPLETION, |
114 | PROP_POPUP_COMPLETION, |
115 | PROP_POPUP_SET_WIDTH, |
116 | PROP_POPUP_SINGLE_MATCH, |
117 | PROP_INLINE_SELECTION, |
118 | PROP_CELL_AREA, |
119 | NUM_PROPERTIES |
120 | }; |
121 | |
122 | |
123 | static void ctk_entry_completion_cell_layout_init (CtkCellLayoutIface *iface); |
124 | static CtkCellArea* ctk_entry_completion_get_area (CtkCellLayout *cell_layout); |
125 | |
126 | static void ctk_entry_completion_constructed (GObject *object); |
127 | static void ctk_entry_completion_set_property (GObject *object, |
128 | guint prop_id, |
129 | const GValue *value, |
130 | GParamSpec *pspec); |
131 | static void ctk_entry_completion_get_property (GObject *object, |
132 | guint prop_id, |
133 | GValue *value, |
134 | GParamSpec *pspec); |
135 | static void ctk_entry_completion_finalize (GObject *object); |
136 | static void ctk_entry_completion_dispose (GObject *object); |
137 | |
138 | static gboolean ctk_entry_completion_visible_func (CtkTreeModel *model, |
139 | CtkTreeIter *iter, |
140 | gpointer data); |
141 | static gboolean ctk_entry_completion_popup_key_event (CtkWidget *widget, |
142 | CdkEventKey *event, |
143 | gpointer user_data); |
144 | static gboolean ctk_entry_completion_popup_button_press (CtkWidget *widget, |
145 | CdkEventButton *event, |
146 | gpointer user_data); |
147 | static gboolean ctk_entry_completion_list_button_press (CtkWidget *widget, |
148 | CdkEventButton *event, |
149 | gpointer user_data); |
150 | static gboolean ctk_entry_completion_action_button_press (CtkWidget *widget, |
151 | CdkEventButton *event, |
152 | gpointer user_data); |
153 | static void ctk_entry_completion_selection_changed (CtkTreeSelection *selection, |
154 | gpointer data); |
155 | static gboolean ctk_entry_completion_list_enter_notify (CtkWidget *widget, |
156 | CdkEventCrossing *event, |
157 | gpointer data); |
158 | static gboolean ctk_entry_completion_list_motion_notify (CtkWidget *widget, |
159 | CdkEventMotion *event, |
160 | gpointer data); |
161 | static void ctk_entry_completion_insert_action (CtkEntryCompletion *completion, |
162 | gint index, |
163 | const gchar *string, |
164 | gboolean markup); |
165 | static void ctk_entry_completion_action_data_func (CtkTreeViewColumn *tree_column, |
166 | CtkCellRenderer *cell, |
167 | CtkTreeModel *model, |
168 | CtkTreeIter *iter, |
169 | gpointer data); |
170 | |
171 | static gboolean ctk_entry_completion_match_selected (CtkEntryCompletion *completion, |
172 | CtkTreeModel *model, |
173 | CtkTreeIter *iter); |
174 | static gboolean ctk_entry_completion_real_insert_prefix (CtkEntryCompletion *completion, |
175 | const gchar *prefix); |
176 | static gboolean ctk_entry_completion_cursor_on_match (CtkEntryCompletion *completion, |
177 | CtkTreeModel *model, |
178 | CtkTreeIter *iter); |
179 | static gboolean ctk_entry_completion_insert_completion (CtkEntryCompletion *completion, |
180 | CtkTreeModel *model, |
181 | CtkTreeIter *iter); |
182 | static void ctk_entry_completion_insert_completion_text (CtkEntryCompletion *completion, |
183 | const gchar *text); |
184 | static void connect_completion_signals (CtkEntryCompletion *completion); |
185 | static void disconnect_completion_signals (CtkEntryCompletion *completion); |
186 | |
187 | |
188 | static GParamSpec *entry_completion_props[NUM_PROPERTIES] = { NULL((void*)0), }; |
189 | |
190 | static guint entry_completion_signals[LAST_SIGNAL] = { 0 }; |
191 | |
192 | /* CtkBuildable */ |
193 | static void ctk_entry_completion_buildable_init (CtkBuildableIface *iface); |
194 | |
195 | G_DEFINE_TYPE_WITH_CODE (CtkEntryCompletion, ctk_entry_completion, G_TYPE_OBJECT,static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
196 | G_ADD_PRIVATE (CtkEntryCompletion)static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
197 | G_IMPLEMENT_INTERFACE (CTK_TYPE_CELL_LAYOUT,static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
198 | ctk_entry_completion_cell_layout_init)static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
199 | G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
200 | ctk_entry_completion_buildable_init))static void ctk_entry_completion_init (CtkEntryCompletion *self ); static void ctk_entry_completion_class_init (CtkEntryCompletionClass *klass); static GType ctk_entry_completion_get_type_once (void ); static gpointer ctk_entry_completion_parent_class = ((void *)0); static gint CtkEntryCompletion_private_offset; static void ctk_entry_completion_class_intern_init (gpointer klass) { ctk_entry_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEntryCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEntryCompletion_private_offset ); ctk_entry_completion_class_init ((CtkEntryCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_entry_completion_get_instance_private (CtkEntryCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEntryCompletion_private_offset )))); } GType ctk_entry_completion_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_entry_completion_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_entry_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkEntryCompletion" ), sizeof (CtkEntryCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_entry_completion_class_intern_init, sizeof (CtkEntryCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_entry_completion_init , (GTypeFlags) 0); { {{ CtkEntryCompletion_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkEntryCompletionPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_cell_layout_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_cell_layout_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_entry_completion_buildable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
201 | |
202 | |
203 | static void |
204 | ctk_entry_completion_class_init (CtkEntryCompletionClass *klass) |
205 | { |
206 | GObjectClass *object_class; |
207 | |
208 | object_class = (GObjectClass *)klass; |
209 | |
210 | object_class->constructed = ctk_entry_completion_constructed; |
211 | object_class->set_property = ctk_entry_completion_set_property; |
212 | object_class->get_property = ctk_entry_completion_get_property; |
213 | object_class->dispose = ctk_entry_completion_dispose; |
214 | object_class->finalize = ctk_entry_completion_finalize; |
215 | |
216 | klass->match_selected = ctk_entry_completion_match_selected; |
217 | klass->insert_prefix = ctk_entry_completion_real_insert_prefix; |
218 | klass->cursor_on_match = ctk_entry_completion_cursor_on_match; |
219 | klass->no_matches = NULL((void*)0); |
220 | |
221 | /** |
222 | * CtkEntryCompletion::insert-prefix: |
223 | * @widget: the object which received the signal |
224 | * @prefix: the common prefix of all possible completions |
225 | * |
226 | * Gets emitted when the inline autocompletion is triggered. |
227 | * The default behaviour is to make the entry display the |
228 | * whole prefix and select the newly inserted part. |
229 | * |
230 | * Applications may connect to this signal in order to insert only a |
231 | * smaller part of the @prefix into the entry - e.g. the entry used in |
232 | * the #CtkFileChooser inserts only the part of the prefix up to the |
233 | * next '/'. |
234 | * |
235 | * Returns: %TRUE if the signal has been handled |
236 | * |
237 | * Since: 2.6 |
238 | */ |
239 | entry_completion_signals[INSERT_PREFIX] = |
240 | g_signal_new (I_("insert-prefix")g_intern_static_string ("insert-prefix"), |
241 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), |
242 | G_SIGNAL_RUN_LAST, |
243 | G_STRUCT_OFFSET (CtkEntryCompletionClass, insert_prefix)((glong) __builtin_offsetof(CtkEntryCompletionClass, insert_prefix )), |
244 | _ctk_boolean_handled_accumulator, NULL((void*)0), |
245 | _ctk_marshal_BOOLEAN__STRING, |
246 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 1, |
247 | G_TYPE_STRING((GType) ((16) << (2)))); |
248 | |
249 | /** |
250 | * CtkEntryCompletion::match-selected: |
251 | * @widget: the object which received the signal |
252 | * @model: the #CtkTreeModel containing the matches |
253 | * @iter: a #CtkTreeIter positioned at the selected match |
254 | * |
255 | * Gets emitted when a match from the list is selected. |
256 | * The default behaviour is to replace the contents of the |
257 | * entry with the contents of the text column in the row |
258 | * pointed to by @iter. |
259 | * |
260 | * Note that @model is the model that was passed to |
261 | * ctk_entry_completion_set_model(). |
262 | * |
263 | * Returns: %TRUE if the signal has been handled |
264 | * |
265 | * Since: 2.4 |
266 | */ |
267 | entry_completion_signals[MATCH_SELECTED] = |
268 | g_signal_new (I_("match-selected")g_intern_static_string ("match-selected"), |
269 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), |
270 | G_SIGNAL_RUN_LAST, |
271 | G_STRUCT_OFFSET (CtkEntryCompletionClass, match_selected)((glong) __builtin_offsetof(CtkEntryCompletionClass, match_selected )), |
272 | _ctk_boolean_handled_accumulator, NULL((void*)0), |
273 | _ctk_marshal_BOOLEAN__OBJECT_BOXED, |
274 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 2, |
275 | CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()), |
276 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ())); |
277 | |
278 | /** |
279 | * CtkEntryCompletion::cursor-on-match: |
280 | * @widget: the object which received the signal |
281 | * @model: the #CtkTreeModel containing the matches |
282 | * @iter: a #CtkTreeIter positioned at the selected match |
283 | * |
284 | * Gets emitted when a match from the cursor is on a match |
285 | * of the list. The default behaviour is to replace the contents |
286 | * of the entry with the contents of the text column in the row |
287 | * pointed to by @iter. |
288 | * |
289 | * Note that @model is the model that was passed to |
290 | * ctk_entry_completion_set_model(). |
291 | * |
292 | * Returns: %TRUE if the signal has been handled |
293 | * |
294 | * Since: 2.12 |
295 | */ |
296 | entry_completion_signals[CURSOR_ON_MATCH] = |
297 | g_signal_new (I_("cursor-on-match")g_intern_static_string ("cursor-on-match"), |
298 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), |
299 | G_SIGNAL_RUN_LAST, |
300 | G_STRUCT_OFFSET (CtkEntryCompletionClass, cursor_on_match)((glong) __builtin_offsetof(CtkEntryCompletionClass, cursor_on_match )), |
301 | _ctk_boolean_handled_accumulator, NULL((void*)0), |
302 | _ctk_marshal_BOOLEAN__OBJECT_BOXED, |
303 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 2, |
304 | CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()), |
305 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ())); |
306 | |
307 | /** |
308 | * CtkEntryCompletion::no-matches: |
309 | * @widget: the object which received the signal |
310 | * |
311 | * Gets emitted when the filter model has zero |
312 | * number of rows in completion_complete method. |
313 | * (In other words when CtkEntryCompletion is out of |
314 | * suggestions) |
315 | * |
316 | * Since: 3.14 |
317 | */ |
318 | entry_completion_signals[NO_MATCHES] = |
319 | g_signal_new (I_("no-matches")g_intern_static_string ("no-matches"), |
320 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), |
321 | G_SIGNAL_RUN_LAST, |
322 | G_STRUCT_OFFSET (CtkEntryCompletionClass, no_matches)((glong) __builtin_offsetof(CtkEntryCompletionClass, no_matches )), |
323 | NULL((void*)0), NULL((void*)0), |
324 | NULL((void*)0), |
325 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
326 | |
327 | /** |
328 | * CtkEntryCompletion::action-activated: |
329 | * @widget: the object which received the signal |
330 | * @index: the index of the activated action |
331 | * |
332 | * Gets emitted when an action is activated. |
333 | * |
334 | * Since: 2.4 |
335 | */ |
336 | entry_completion_signals[ACTION_ACTIVATED] = |
337 | g_signal_new (I_("action-activated")g_intern_static_string ("action-activated"), |
338 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), |
339 | G_SIGNAL_RUN_LAST, |
340 | G_STRUCT_OFFSET (CtkEntryCompletionClass, action_activated)((glong) __builtin_offsetof(CtkEntryCompletionClass, action_activated )), |
341 | NULL((void*)0), NULL((void*)0), |
342 | NULL((void*)0), |
343 | G_TYPE_NONE((GType) ((1) << (2))), 1, |
344 | G_TYPE_INT((GType) ((6) << (2)))); |
345 | |
346 | entry_completion_props[PROP_MODEL] = |
347 | g_param_spec_object ("model", |
348 | P_("Completion Model")g_dgettext("ctk30" "-properties","Completion Model"), |
349 | P_("The model to find matches in")g_dgettext("ctk30" "-properties","The model to find matches in" ), |
350 | CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()), |
351 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); |
352 | |
353 | entry_completion_props[PROP_MINIMUM_KEY_LENGTH] = |
354 | g_param_spec_int ("minimum-key-length", |
355 | P_("Minimum Key Length")g_dgettext("ctk30" "-properties","Minimum Key Length"), |
356 | P_("Minimum length of the search key in order to look up matches")g_dgettext("ctk30" "-properties","Minimum length of the search key in order to look up matches" ), |
357 | 0, G_MAXINT2147483647, 1, |
358 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
359 | |
360 | /** |
361 | * CtkEntryCompletion:text-column: |
362 | * |
363 | * The column of the model containing the strings. |
364 | * Note that the strings must be UTF-8. |
365 | * |
366 | * Since: 2.6 |
367 | */ |
368 | entry_completion_props[PROP_TEXT_COLUMN] = |
369 | g_param_spec_int ("text-column", |
370 | P_("Text column")g_dgettext("ctk30" "-properties","Text column"), |
371 | P_("The column of the model containing the strings.")g_dgettext("ctk30" "-properties","The column of the model containing the strings." ), |
372 | -1, G_MAXINT2147483647, -1, |
373 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); |
374 | |
375 | /** |
376 | * CtkEntryCompletion:inline-completion: |
377 | * |
378 | * Determines whether the common prefix of the possible completions |
379 | * should be inserted automatically in the entry. Note that this |
380 | * requires text-column to be set, even if you are using a custom |
381 | * match function. |
382 | * |
383 | * Since: 2.6 |
384 | **/ |
385 | entry_completion_props[PROP_INLINE_COMPLETION] = |
386 | g_param_spec_boolean ("inline-completion", |
387 | P_("Inline completion")g_dgettext("ctk30" "-properties","Inline completion"), |
388 | P_("Whether the common prefix should be inserted automatically")g_dgettext("ctk30" "-properties","Whether the common prefix should be inserted automatically" ), |
389 | FALSE(0), |
390 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
391 | |
392 | /** |
393 | * CtkEntryCompletion:popup-completion: |
394 | * |
395 | * Determines whether the possible completions should be |
396 | * shown in a popup window. |
397 | * |
398 | * Since: 2.6 |
399 | **/ |
400 | entry_completion_props[PROP_POPUP_COMPLETION] = |
401 | g_param_spec_boolean ("popup-completion", |
402 | P_("Popup completion")g_dgettext("ctk30" "-properties","Popup completion"), |
403 | P_("Whether the completions should be shown in a popup window")g_dgettext("ctk30" "-properties","Whether the completions should be shown in a popup window" ), |
404 | TRUE(!(0)), |
405 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
406 | |
407 | /** |
408 | * CtkEntryCompletion:popup-set-width: |
409 | * |
410 | * Determines whether the completions popup window will be |
411 | * resized to the width of the entry. |
412 | * |
413 | * Since: 2.8 |
414 | */ |
415 | entry_completion_props[PROP_POPUP_SET_WIDTH] = |
416 | g_param_spec_boolean ("popup-set-width", |
417 | P_("Popup set width")g_dgettext("ctk30" "-properties","Popup set width"), |
418 | P_("If TRUE, the popup window will have the same size as the entry")g_dgettext("ctk30" "-properties","If TRUE, the popup window will have the same size as the entry" ), |
419 | TRUE(!(0)), |
420 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
421 | |
422 | /** |
423 | * CtkEntryCompletion:popup-single-match: |
424 | * |
425 | * Determines whether the completions popup window will shown |
426 | * for a single possible completion. You probably want to set |
427 | * this to %FALSE if you are using |
428 | * [inline completion][CtkEntryCompletion--inline-completion]. |
429 | * |
430 | * Since: 2.8 |
431 | */ |
432 | entry_completion_props[PROP_POPUP_SINGLE_MATCH] = |
433 | g_param_spec_boolean ("popup-single-match", |
434 | P_("Popup single match")g_dgettext("ctk30" "-properties","Popup single match"), |
435 | P_("If TRUE, the popup window will appear for a single match.")g_dgettext("ctk30" "-properties","If TRUE, the popup window will appear for a single match." ), |
436 | TRUE(!(0)), |
437 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
438 | |
439 | /** |
440 | * CtkEntryCompletion:inline-selection: |
441 | * |
442 | * Determines whether the possible completions on the popup |
443 | * will appear in the entry as you navigate through them. |
444 | * |
445 | * Since: 2.12 |
446 | */ |
447 | entry_completion_props[PROP_INLINE_SELECTION] = |
448 | g_param_spec_boolean ("inline-selection", |
449 | P_("Inline selection")g_dgettext("ctk30" "-properties","Inline selection"), |
450 | P_("Your description here")g_dgettext("ctk30" "-properties","Your description here"), |
451 | FALSE(0), |
452 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
453 | |
454 | /** |
455 | * CtkEntryCompletion:cell-area: |
456 | * |
457 | * The #CtkCellArea used to layout cell renderers in the treeview column. |
458 | * |
459 | * If no area is specified when creating the entry completion with |
460 | * ctk_entry_completion_new_with_area() a horizontally oriented |
461 | * #CtkCellAreaBox will be used. |
462 | * |
463 | * Since: 3.0 |
464 | */ |
465 | entry_completion_props[PROP_CELL_AREA] = |
466 | g_param_spec_object ("cell-area", |
467 | P_("Cell Area")g_dgettext("ctk30" "-properties","Cell Area"), |
468 | P_("The CtkCellArea used to layout cells")g_dgettext("ctk30" "-properties","The CtkCellArea used to layout cells" ), |
469 | CTK_TYPE_CELL_AREA(ctk_cell_area_get_type ()), |
470 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY); |
471 | |
472 | g_object_class_install_properties (object_class, NUM_PROPERTIES, entry_completion_props); |
473 | } |
474 | |
475 | |
476 | static void |
477 | ctk_entry_completion_buildable_custom_tag_end (CtkBuildable *buildable, |
478 | CtkBuilder *builder, |
479 | GObject *child, |
480 | const gchar *tagname, |
481 | gpointer *data) |
482 | { |
483 | /* Just ignore the boolean return from here */ |
484 | _ctk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname, data); |
485 | } |
486 | |
487 | static void |
488 | ctk_entry_completion_buildable_init (CtkBuildableIface *iface) |
489 | { |
490 | iface->add_child = _ctk_cell_layout_buildable_add_child; |
491 | iface->custom_tag_start = _ctk_cell_layout_buildable_custom_tag_start; |
492 | iface->custom_tag_end = ctk_entry_completion_buildable_custom_tag_end; |
493 | } |
494 | |
495 | static void |
496 | ctk_entry_completion_cell_layout_init (CtkCellLayoutIface *iface) |
497 | { |
498 | iface->get_area = ctk_entry_completion_get_area; |
499 | } |
500 | |
501 | static void |
502 | ctk_entry_completion_init (CtkEntryCompletion *completion) |
503 | { |
504 | CtkEntryCompletionPrivate *priv; |
505 | |
506 | /* yes, also priv, need to keep the code readable */ |
507 | completion->priv = ctk_entry_completion_get_instance_private (completion); |
508 | priv = completion->priv; |
509 | |
510 | priv->minimum_key_length = 1; |
511 | priv->text_column = -1; |
512 | priv->has_completion = FALSE(0); |
513 | priv->inline_completion = FALSE(0); |
514 | priv->popup_completion = TRUE(!(0)); |
515 | priv->popup_set_width = TRUE(!(0)); |
516 | priv->popup_single_match = TRUE(!(0)); |
517 | priv->inline_selection = FALSE(0); |
518 | |
519 | priv->filter_model = NULL((void*)0); |
520 | } |
521 | |
522 | static void |
523 | ctk_entry_completion_constructed (GObject *object) |
524 | { |
525 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (object)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_entry_completion_get_type ( ))))))); |
526 | CtkEntryCompletionPrivate *priv = completion->priv; |
527 | CtkCellRenderer *cell; |
528 | CtkTreeSelection *sel; |
529 | CtkWidget *popup_frame; |
530 | |
531 | G_OBJECT_CLASS (ctk_entry_completion_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_entry_completion_parent_class)), (((GType) ((20) << (2))))))))->constructed (object); |
532 | |
533 | if (!priv->cell_area) |
534 | { |
535 | priv->cell_area = ctk_cell_area_box_new (); |
536 | g_object_ref_sink (priv->cell_area)((__typeof__ (priv->cell_area)) (g_object_ref_sink) (priv-> cell_area)); |
537 | } |
538 | |
539 | /* completions */ |
540 | priv->tree_view = ctk_tree_view_new (); |
541 | g_signal_connect (priv->tree_view, "button-press-event",g_signal_connect_data ((priv->tree_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_list_button_press))), ( completion), ((void*)0), (GConnectFlags) 0) |
542 | G_CALLBACK (ctk_entry_completion_list_button_press),g_signal_connect_data ((priv->tree_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_list_button_press))), ( completion), ((void*)0), (GConnectFlags) 0) |
543 | completion)g_signal_connect_data ((priv->tree_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_list_button_press))), ( completion), ((void*)0), (GConnectFlags) 0); |
544 | g_signal_connect (priv->tree_view, "enter-notify-event",g_signal_connect_data ((priv->tree_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0) |
545 | G_CALLBACK (ctk_entry_completion_list_enter_notify),g_signal_connect_data ((priv->tree_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0) |
546 | completion)g_signal_connect_data ((priv->tree_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0); |
547 | g_signal_connect (priv->tree_view, "motion-notify-event",g_signal_connect_data ((priv->tree_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0) |
548 | G_CALLBACK (ctk_entry_completion_list_motion_notify),g_signal_connect_data ((priv->tree_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0) |
549 | completion)g_signal_connect_data ((priv->tree_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0); |
550 | |
551 | ctk_tree_view_set_headers_visible (CTK_TREE_VIEW (priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->tree_view)), ((ctk_tree_view_get_type ())))))), FALSE(0)); |
552 | ctk_tree_view_set_hover_selection (CTK_TREE_VIEW (priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->tree_view)), ((ctk_tree_view_get_type ())))))), TRUE(!(0))); |
553 | |
554 | sel = ctk_tree_view_get_selection (CTK_TREE_VIEW (priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->tree_view)), ((ctk_tree_view_get_type ()))))))); |
555 | ctk_tree_selection_set_mode (sel, CTK_SELECTION_SINGLE); |
556 | ctk_tree_selection_unselect_all (sel); |
557 | g_signal_connect (sel, "changed",g_signal_connect_data ((sel), ("changed"), (((GCallback) (ctk_entry_completion_selection_changed ))), (completion), ((void*)0), (GConnectFlags) 0) |
558 | G_CALLBACK (ctk_entry_completion_selection_changed),g_signal_connect_data ((sel), ("changed"), (((GCallback) (ctk_entry_completion_selection_changed ))), (completion), ((void*)0), (GConnectFlags) 0) |
559 | completion)g_signal_connect_data ((sel), ("changed"), (((GCallback) (ctk_entry_completion_selection_changed ))), (completion), ((void*)0), (GConnectFlags) 0); |
560 | priv->first_sel_changed = TRUE(!(0)); |
561 | |
562 | priv->column = ctk_tree_view_column_new_with_area (priv->cell_area); |
563 | ctk_tree_view_append_column (CTK_TREE_VIEW (priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->tree_view)), ((ctk_tree_view_get_type ())))))), priv->column); |
564 | |
565 | priv->scrolled_window = ctk_scrolled_window_new (NULL((void*)0), NULL((void*)0)); |
566 | ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (priv->scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((priv->scrolled_window)), ((ctk_scrolled_window_get_type ())))))), |
567 | CTK_POLICY_NEVER, |
568 | CTK_POLICY_AUTOMATIC); |
569 | ctk_scrolled_window_set_shadow_type (CTK_SCROLLED_WINDOW (priv->scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((priv->scrolled_window)), ((ctk_scrolled_window_get_type ())))))), |
570 | CTK_SHADOW_NONE); |
571 | |
572 | /* a nasty hack to get the completions treeview to size nicely */ |
573 | ctk_widget_set_size_request (ctk_scrolled_window_get_vscrollbar (CTK_SCROLLED_WINDOW (priv->scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((priv->scrolled_window)), ((ctk_scrolled_window_get_type ()))))))), |
574 | -1, 0); |
575 | |
576 | /* actions */ |
577 | priv->actions = ctk_list_store_new (2, G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_BOOLEAN((GType) ((5) << (2)))); |
578 | |
579 | priv->action_view = |
580 | ctk_tree_view_new_with_model (CTK_TREE_MODEL (priv->actions)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->actions)), ((ctk_tree_model_get_type ()))))))); |
581 | g_object_ref_sink (priv->action_view)((__typeof__ (priv->action_view)) (g_object_ref_sink) (priv ->action_view)); |
582 | g_signal_connect (priv->action_view, "button-press-event",g_signal_connect_data ((priv->action_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_action_button_press))) , (completion), ((void*)0), (GConnectFlags) 0) |
583 | G_CALLBACK (ctk_entry_completion_action_button_press),g_signal_connect_data ((priv->action_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_action_button_press))) , (completion), ((void*)0), (GConnectFlags) 0) |
584 | completion)g_signal_connect_data ((priv->action_view), ("button-press-event" ), (((GCallback) (ctk_entry_completion_action_button_press))) , (completion), ((void*)0), (GConnectFlags) 0); |
585 | g_signal_connect (priv->action_view, "enter-notify-event",g_signal_connect_data ((priv->action_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0) |
586 | G_CALLBACK (ctk_entry_completion_list_enter_notify),g_signal_connect_data ((priv->action_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0) |
587 | completion)g_signal_connect_data ((priv->action_view), ("enter-notify-event" ), (((GCallback) (ctk_entry_completion_list_enter_notify))), ( completion), ((void*)0), (GConnectFlags) 0); |
588 | g_signal_connect (priv->action_view, "motion-notify-event",g_signal_connect_data ((priv->action_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0) |
589 | G_CALLBACK (ctk_entry_completion_list_motion_notify),g_signal_connect_data ((priv->action_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0) |
590 | completion)g_signal_connect_data ((priv->action_view), ("motion-notify-event" ), (((GCallback) (ctk_entry_completion_list_motion_notify))), (completion), ((void*)0), (GConnectFlags) 0); |
591 | ctk_tree_view_set_headers_visible (CTK_TREE_VIEW (priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->action_view)), ((ctk_tree_view_get_type ()))))) ), FALSE(0)); |
592 | ctk_tree_view_set_hover_selection (CTK_TREE_VIEW (priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->action_view)), ((ctk_tree_view_get_type ()))))) ), TRUE(!(0))); |
593 | |
594 | sel = ctk_tree_view_get_selection (CTK_TREE_VIEW (priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->action_view)), ((ctk_tree_view_get_type ()))))) )); |
595 | ctk_tree_selection_set_mode (sel, CTK_SELECTION_SINGLE); |
596 | ctk_tree_selection_unselect_all (sel); |
597 | |
598 | cell = ctk_cell_renderer_text_new (); |
599 | ctk_tree_view_insert_column_with_data_func (CTK_TREE_VIEW (priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->action_view)), ((ctk_tree_view_get_type ()))))) ), |
600 | 0, "", |
601 | cell, |
602 | ctk_entry_completion_action_data_func, |
603 | NULL((void*)0), |
604 | NULL((void*)0)); |
605 | |
606 | /* pack it all */ |
607 | priv->popup_window = ctk_window_new (CTK_WINDOW_POPUP); |
608 | ctk_window_set_use_subsurface (CTK_WINDOW (priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->popup_window)), ((ctk_window_get_type ())))))), TRUE(!(0))); |
609 | ctk_window_set_resizable (CTK_WINDOW (priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->popup_window)), ((ctk_window_get_type ())))))), FALSE(0)); |
610 | ctk_window_set_type_hint (CTK_WINDOW(priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->popup_window)), ((ctk_window_get_type ())))))), |
611 | CDK_WINDOW_TYPE_HINT_COMBO); |
612 | |
613 | g_signal_connect (priv->popup_window, "key-press-event",g_signal_connect_data ((priv->popup_window), ("key-press-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0) |
614 | G_CALLBACK (ctk_entry_completion_popup_key_event),g_signal_connect_data ((priv->popup_window), ("key-press-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0) |
615 | completion)g_signal_connect_data ((priv->popup_window), ("key-press-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0); |
616 | g_signal_connect (priv->popup_window, "key-release-event",g_signal_connect_data ((priv->popup_window), ("key-release-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0) |
617 | G_CALLBACK (ctk_entry_completion_popup_key_event),g_signal_connect_data ((priv->popup_window), ("key-release-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0) |
618 | completion)g_signal_connect_data ((priv->popup_window), ("key-release-event" ), (((GCallback) (ctk_entry_completion_popup_key_event))), (completion ), ((void*)0), (GConnectFlags) 0); |
619 | g_signal_connect (priv->popup_window, "button-press-event",g_signal_connect_data ((priv->popup_window), ("button-press-event" ), (((GCallback) (ctk_entry_completion_popup_button_press))), (completion), ((void*)0), (GConnectFlags) 0) |
620 | G_CALLBACK (ctk_entry_completion_popup_button_press),g_signal_connect_data ((priv->popup_window), ("button-press-event" ), (((GCallback) (ctk_entry_completion_popup_button_press))), (completion), ((void*)0), (GConnectFlags) 0) |
621 | completion)g_signal_connect_data ((priv->popup_window), ("button-press-event" ), (((GCallback) (ctk_entry_completion_popup_button_press))), (completion), ((void*)0), (GConnectFlags) 0); |
622 | |
623 | popup_frame = ctk_frame_new (NULL((void*)0)); |
624 | ctk_frame_set_shadow_type (CTK_FRAME (popup_frame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((popup_frame)), ((ctk_frame_get_type ())))))), |
625 | CTK_SHADOW_ETCHED_IN); |
626 | ctk_widget_show (popup_frame); |
627 | ctk_container_add (CTK_CONTAINER (priv->popup_window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->popup_window)), ((ctk_container_get_type ())))) )), popup_frame); |
628 | |
629 | priv->vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0); |
630 | ctk_container_add (CTK_CONTAINER (popup_frame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((popup_frame)), ((ctk_container_get_type ())))))), priv->vbox); |
631 | |
632 | ctk_container_add (CTK_CONTAINER (priv->scrolled_window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->scrolled_window)), ((ctk_container_get_type ()) ))))), priv->tree_view); |
633 | ctk_box_pack_start (CTK_BOX (priv->vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->vbox)), ((ctk_box_get_type ())))))), priv->scrolled_window, |
634 | TRUE(!(0)), TRUE(!(0)), 0); |
635 | |
636 | /* we don't want to see the action treeview when no actions have |
637 | * been inserted, so we pack the action treeview after the first |
638 | * action has been added |
639 | */ |
640 | } |
641 | |
642 | |
643 | static void |
644 | ctk_entry_completion_set_property (GObject *object, |
645 | guint prop_id, |
646 | const GValue *value, |
647 | GParamSpec *pspec) |
648 | { |
649 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (object)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_entry_completion_get_type ( ))))))); |
650 | CtkEntryCompletionPrivate *priv = completion->priv; |
651 | CtkCellArea *area; |
652 | |
653 | switch (prop_id) |
654 | { |
655 | case PROP_MODEL: |
656 | ctk_entry_completion_set_model (completion, |
657 | g_value_get_object (value)); |
658 | break; |
659 | |
660 | case PROP_MINIMUM_KEY_LENGTH: |
661 | ctk_entry_completion_set_minimum_key_length (completion, |
662 | g_value_get_int (value)); |
663 | break; |
664 | |
665 | case PROP_TEXT_COLUMN: |
666 | priv->text_column = g_value_get_int (value); |
667 | break; |
668 | |
669 | case PROP_INLINE_COMPLETION: |
670 | ctk_entry_completion_set_inline_completion (completion, |
671 | g_value_get_boolean (value)); |
672 | break; |
673 | |
674 | case PROP_POPUP_COMPLETION: |
675 | ctk_entry_completion_set_popup_completion (completion, |
676 | g_value_get_boolean (value)); |
677 | break; |
678 | |
679 | case PROP_POPUP_SET_WIDTH: |
680 | ctk_entry_completion_set_popup_set_width (completion, |
681 | g_value_get_boolean (value)); |
682 | break; |
683 | |
684 | case PROP_POPUP_SINGLE_MATCH: |
685 | ctk_entry_completion_set_popup_single_match (completion, |
686 | g_value_get_boolean (value)); |
687 | break; |
688 | |
689 | case PROP_INLINE_SELECTION: |
690 | ctk_entry_completion_set_inline_selection (completion, |
691 | g_value_get_boolean (value)); |
692 | break; |
693 | |
694 | case PROP_CELL_AREA: |
695 | /* Construct-only, can only be assigned once */ |
696 | area = g_value_get_object (value); |
697 | if (area) |
698 | { |
699 | if (priv->cell_area != NULL((void*)0)) |
700 | { |
701 | g_warning ("cell-area has already been set, ignoring construct property"); |
702 | g_object_ref_sink (area)((__typeof__ (area)) (g_object_ref_sink) (area)); |
703 | g_object_unref (area); |
704 | } |
705 | else |
706 | priv->cell_area = g_object_ref_sink (area)((__typeof__ (area)) (g_object_ref_sink) (area)); |
707 | } |
708 | break; |
709 | |
710 | default: |
711 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkentrycompletion.c", 711, ("property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
712 | break; |
713 | } |
714 | } |
715 | |
716 | static void |
717 | ctk_entry_completion_get_property (GObject *object, |
718 | guint prop_id, |
719 | GValue *value, |
720 | GParamSpec *pspec) |
721 | { |
722 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (object)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_entry_completion_get_type ( ))))))); |
723 | |
724 | switch (prop_id) |
725 | { |
726 | case PROP_MODEL: |
727 | g_value_set_object (value, |
728 | ctk_entry_completion_get_model (completion)); |
729 | break; |
730 | |
731 | case PROP_MINIMUM_KEY_LENGTH: |
732 | g_value_set_int (value, ctk_entry_completion_get_minimum_key_length (completion)); |
733 | break; |
734 | |
735 | case PROP_TEXT_COLUMN: |
736 | g_value_set_int (value, ctk_entry_completion_get_text_column (completion)); |
737 | break; |
738 | |
739 | case PROP_INLINE_COMPLETION: |
740 | g_value_set_boolean (value, ctk_entry_completion_get_inline_completion (completion)); |
741 | break; |
742 | |
743 | case PROP_POPUP_COMPLETION: |
744 | g_value_set_boolean (value, ctk_entry_completion_get_popup_completion (completion)); |
745 | break; |
746 | |
747 | case PROP_POPUP_SET_WIDTH: |
748 | g_value_set_boolean (value, ctk_entry_completion_get_popup_set_width (completion)); |
749 | break; |
750 | |
751 | case PROP_POPUP_SINGLE_MATCH: |
752 | g_value_set_boolean (value, ctk_entry_completion_get_popup_single_match (completion)); |
753 | break; |
754 | |
755 | case PROP_INLINE_SELECTION: |
756 | g_value_set_boolean (value, ctk_entry_completion_get_inline_selection (completion)); |
757 | break; |
758 | |
759 | case PROP_CELL_AREA: |
760 | g_value_set_object (value, completion->priv->cell_area); |
761 | break; |
762 | |
763 | default: |
764 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkentrycompletion.c", 764, ("property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
765 | break; |
766 | } |
767 | } |
768 | |
769 | static void |
770 | ctk_entry_completion_finalize (GObject *object) |
771 | { |
772 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (object)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_entry_completion_get_type ( ))))))); |
773 | CtkEntryCompletionPrivate *priv = completion->priv; |
774 | |
775 | g_free (priv->case_normalized_key); |
776 | g_free (priv->completion_prefix); |
777 | |
778 | if (priv->match_notify) |
779 | (* priv->match_notify) (priv->match_data); |
780 | |
781 | G_OBJECT_CLASS (ctk_entry_completion_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_entry_completion_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); |
782 | } |
783 | |
784 | static void |
785 | ctk_entry_completion_dispose (GObject *object) |
786 | { |
787 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (object)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_entry_completion_get_type ( ))))))); |
788 | CtkEntryCompletionPrivate *priv = completion->priv; |
789 | |
790 | if (priv->tree_view) |
791 | { |
792 | ctk_widget_destroy (priv->tree_view); |
793 | priv->tree_view = NULL((void*)0); |
794 | } |
795 | |
796 | if (priv->entry) |
797 | ctk_entry_set_completion (CTK_ENTRY (priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->entry)), ((ctk_entry_get_type ())))))), NULL((void*)0)); |
798 | |
799 | if (priv->actions) |
800 | { |
801 | g_object_unref (priv->actions); |
802 | priv->actions = NULL((void*)0); |
803 | } |
804 | |
805 | if (priv->action_view) |
806 | { |
807 | g_object_unref (priv->action_view); |
808 | priv->action_view = NULL((void*)0); |
809 | } |
810 | |
811 | if (priv->popup_window) |
812 | { |
813 | ctk_widget_destroy (priv->popup_window); |
814 | priv->popup_window = NULL((void*)0); |
815 | } |
816 | |
817 | if (priv->cell_area) |
818 | { |
819 | g_object_unref (priv->cell_area); |
820 | priv->cell_area = NULL((void*)0); |
821 | } |
822 | |
823 | G_OBJECT_CLASS (ctk_entry_completion_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_entry_completion_parent_class)), (((GType) ((20) << (2))))))))->dispose (object); |
824 | } |
825 | |
826 | /* implement cell layout interface (only need to return the underlying cell area) */ |
827 | static CtkCellArea* |
828 | ctk_entry_completion_get_area (CtkCellLayout *cell_layout) |
829 | { |
830 | CtkEntryCompletionPrivate *priv; |
831 | |
832 | priv = CTK_ENTRY_COMPLETION (cell_layout)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((cell_layout)), ((ctk_entry_completion_get_type ()))))))->priv; |
833 | |
834 | if (G_UNLIKELY (!priv->cell_area)(!priv->cell_area)) |
835 | { |
836 | priv->cell_area = ctk_cell_area_box_new (); |
837 | g_object_ref_sink (priv->cell_area)((__typeof__ (priv->cell_area)) (g_object_ref_sink) (priv-> cell_area)); |
838 | } |
839 | |
840 | return priv->cell_area; |
841 | } |
842 | |
843 | /* all those callbacks */ |
844 | static gboolean |
845 | ctk_entry_completion_default_completion_func (CtkEntryCompletion *completion, |
846 | const gchar *key, |
847 | CtkTreeIter *iter, |
848 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
849 | { |
850 | gchar *item = NULL((void*)0); |
851 | gchar *normalized_string; |
852 | gchar *case_normalized_string; |
853 | |
854 | gboolean ret = FALSE(0); |
855 | |
856 | CtkTreeModel *model; |
857 | |
858 | model = ctk_tree_model_filter_get_model (completion->priv->filter_model); |
859 | |
860 | g_return_val_if_fail (ctk_tree_model_get_column_type (model, completion->priv->text_column) == G_TYPE_STRING,do { if ((ctk_tree_model_get_column_type (model, completion-> priv->text_column) == ((GType) ((16) << (2))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "ctk_tree_model_get_column_type (model, completion->priv->text_column) == G_TYPE_STRING" ); return ((0)); } } while (0) |
861 | FALSE)do { if ((ctk_tree_model_get_column_type (model, completion-> priv->text_column) == ((GType) ((16) << (2))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "ctk_tree_model_get_column_type (model, completion->priv->text_column) == G_TYPE_STRING" ); return ((0)); } } while (0); |
862 | |
863 | ctk_tree_model_get (model, iter, |
864 | completion->priv->text_column, &item, |
865 | -1); |
866 | |
867 | if (item != NULL((void*)0)) |
868 | { |
869 | normalized_string = g_utf8_normalize (item, -1, G_NORMALIZE_ALL); |
870 | |
871 | if (normalized_string != NULL((void*)0)) |
872 | { |
873 | case_normalized_string = g_utf8_casefold (normalized_string, -1); |
874 | |
875 | if (!strncmp (key, case_normalized_string, strlen (key))) |
876 | ret = TRUE(!(0)); |
877 | |
878 | g_free (case_normalized_string); |
879 | } |
880 | g_free (normalized_string); |
881 | } |
882 | g_free (item); |
883 | |
884 | return ret; |
885 | } |
886 | |
887 | static gboolean |
888 | ctk_entry_completion_visible_func (CtkTreeModel *model G_GNUC_UNUSED__attribute__ ((__unused__)), |
889 | CtkTreeIter *iter, |
890 | gpointer data) |
891 | { |
892 | gboolean ret = FALSE(0); |
893 | |
894 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((data)), ((ctk_entry_completion_get_type () )))))); |
895 | |
896 | if (!completion->priv->case_normalized_key) |
897 | return ret; |
898 | |
899 | if (completion->priv->match_func) |
900 | ret = (* completion->priv->match_func) (completion, |
901 | completion->priv->case_normalized_key, |
902 | iter, |
903 | completion->priv->match_data); |
904 | else if (completion->priv->text_column >= 0) |
905 | ret = ctk_entry_completion_default_completion_func (completion, |
906 | completion->priv->case_normalized_key, |
907 | iter, |
908 | NULL((void*)0)); |
909 | |
910 | return ret; |
911 | } |
912 | |
913 | static gboolean |
914 | ctk_entry_completion_popup_key_event (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
915 | CdkEventKey *event, |
916 | gpointer user_data) |
917 | { |
918 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
919 | |
920 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
921 | return FALSE(0); |
922 | |
923 | /* propagate event to the entry */ |
924 | ctk_widget_event (completion->priv->entry, (CdkEvent *)event); |
925 | |
926 | return TRUE(!(0)); |
927 | } |
928 | |
929 | static gboolean |
930 | ctk_entry_completion_popup_button_press (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
931 | CdkEventButton *event G_GNUC_UNUSED__attribute__ ((__unused__)), |
932 | gpointer user_data) |
933 | { |
934 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
935 | |
936 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
937 | return FALSE(0); |
938 | |
939 | /* if we come here, it's usually time to popdown */ |
940 | _ctk_entry_completion_popdown (completion); |
941 | |
942 | return TRUE(!(0)); |
943 | } |
944 | |
945 | static gboolean |
946 | ctk_entry_completion_list_button_press (CtkWidget *widget, |
947 | CdkEventButton *event, |
948 | gpointer user_data) |
949 | { |
950 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
951 | CtkTreePath *path = NULL((void*)0); |
952 | |
953 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
954 | return FALSE(0); |
955 | |
956 | if (ctk_tree_view_get_path_at_pos (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
957 | event->x, event->y, |
958 | &path, NULL((void*)0), NULL((void*)0), NULL((void*)0))) |
959 | { |
960 | CtkTreeIter iter; |
961 | gboolean entry_set; |
962 | CtkTreeModel *model; |
963 | CtkTreeIter child_iter; |
964 | |
965 | ctk_tree_model_get_iter (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), |
966 | &iter, path); |
967 | ctk_tree_path_free (path); |
968 | ctk_tree_model_filter_convert_iter_to_child_iter (completion->priv->filter_model, |
969 | &child_iter, |
970 | &iter); |
971 | model = ctk_tree_model_filter_get_model (completion->priv->filter_model); |
972 | |
973 | g_signal_handler_block (completion->priv->entry, |
974 | completion->priv->changed_id); |
975 | g_signal_emit (completion, entry_completion_signals[MATCH_SELECTED], |
976 | 0, model, &child_iter, &entry_set); |
977 | g_signal_handler_unblock (completion->priv->entry, |
978 | completion->priv->changed_id); |
979 | |
980 | _ctk_entry_completion_popdown (completion); |
981 | |
982 | return TRUE(!(0)); |
983 | } |
984 | |
985 | return FALSE(0); |
986 | } |
987 | |
988 | static gboolean |
989 | ctk_entry_completion_action_button_press (CtkWidget *widget, |
990 | CdkEventButton *event, |
991 | gpointer user_data) |
992 | { |
993 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
994 | CtkTreePath *path = NULL((void*)0); |
995 | |
996 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
997 | return FALSE(0); |
998 | |
999 | ctk_entry_reset_im_context (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () ))))))); |
1000 | |
1001 | if (ctk_tree_view_get_path_at_pos (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
1002 | event->x, event->y, |
1003 | &path, NULL((void*)0), NULL((void*)0), NULL((void*)0))) |
1004 | { |
1005 | g_signal_emit (completion, entry_completion_signals[ACTION_ACTIVATED], |
1006 | 0, ctk_tree_path_get_indices (path)[0]); |
1007 | ctk_tree_path_free (path); |
1008 | |
1009 | _ctk_entry_completion_popdown (completion); |
1010 | return TRUE(!(0)); |
1011 | } |
1012 | |
1013 | return FALSE(0); |
1014 | } |
1015 | |
1016 | static void |
1017 | ctk_entry_completion_action_data_func (CtkTreeViewColumn *tree_column G_GNUC_UNUSED__attribute__ ((__unused__)), |
1018 | CtkCellRenderer *cell, |
1019 | CtkTreeModel *model, |
1020 | CtkTreeIter *iter, |
1021 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) |
1022 | { |
1023 | gchar *string = NULL((void*)0); |
1024 | gboolean markup; |
1025 | |
1026 | ctk_tree_model_get (model, iter, |
1027 | 0, &string, |
1028 | 1, &markup, |
1029 | -1); |
1030 | |
1031 | if (!string) |
1032 | return; |
1033 | |
1034 | if (markup) |
1035 | g_object_set (cell, |
1036 | "text", NULL((void*)0), |
1037 | "markup", string, |
1038 | NULL((void*)0)); |
1039 | else |
1040 | g_object_set (cell, |
1041 | "markup", NULL((void*)0), |
1042 | "text", string, |
1043 | NULL((void*)0)); |
1044 | |
1045 | g_free (string); |
1046 | } |
1047 | |
1048 | static void |
1049 | ctk_entry_completion_selection_changed (CtkTreeSelection *selection, |
1050 | gpointer data) |
1051 | { |
1052 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((data)), ((ctk_entry_completion_get_type () )))))); |
1053 | |
1054 | if (completion->priv->first_sel_changed) |
1055 | { |
1056 | completion->priv->first_sel_changed = FALSE(0); |
1057 | if (ctk_widget_is_focus (completion->priv->tree_view)) |
1058 | ctk_tree_selection_unselect_all (selection); |
1059 | } |
1060 | } |
1061 | |
1062 | static void |
1063 | prepare_popup_func (CdkSeat *seat G_GNUC_UNUSED__attribute__ ((__unused__)), |
1064 | CdkWindow *window G_GNUC_UNUSED__attribute__ ((__unused__)), |
1065 | gpointer user_data) |
1066 | { |
1067 | CtkEntryCompletion *completion = user_data; |
1068 | |
1069 | /* prevent the first row being focused */ |
1070 | ctk_widget_grab_focus (completion->priv->tree_view); |
1071 | |
1072 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))))); |
1073 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))))); |
1074 | |
1075 | ctk_widget_show (completion->priv->popup_window); |
1076 | } |
1077 | |
1078 | static void |
1079 | ctk_entry_completion_popup (CtkEntryCompletion *completion) |
1080 | { |
1081 | CtkWidget *toplevel; |
1082 | |
1083 | if (ctk_widget_get_mapped (completion->priv->popup_window)) |
1084 | return; |
1085 | |
1086 | if (!ctk_widget_get_mapped (completion->priv->entry)) |
1087 | return; |
1088 | |
1089 | if (!ctk_widget_has_focus (completion->priv->entry)) |
1090 | return; |
1091 | |
1092 | if (completion->priv->has_grab) |
1093 | return; |
1094 | |
1095 | completion->priv->ignore_enter = TRUE(!(0)); |
1096 | |
1097 | ctk_widget_show_all (completion->priv->vbox); |
1098 | |
1099 | /* default on no match */ |
1100 | completion->priv->current_selected = -1; |
1101 | |
1102 | toplevel = ctk_widget_get_toplevel (completion->priv->entry); |
1103 | if (CTK_IS_WINDOW (toplevel)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (toplevel)); GType __t = ((ctk_window_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; }))))) |
1104 | { |
1105 | ctk_window_set_transient_for (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), |
1106 | CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ()))))))); |
1107 | ctk_window_group_add_window (ctk_window_get_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ()))))))), |
1108 | CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ()))))))); |
1109 | } |
1110 | |
1111 | ctk_window_set_screen (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), |
1112 | ctk_widget_get_screen (completion->priv->entry)); |
1113 | |
1114 | _ctk_entry_completion_resize_popup (completion); |
1115 | |
1116 | if (completion->priv->device) |
1117 | { |
1118 | ctk_grab_add (completion->priv->popup_window); |
1119 | cdk_seat_grab (cdk_device_get_seat (completion->priv->device), |
1120 | ctk_widget_get_window (completion->priv->popup_window), |
1121 | CDK_SEAT_CAPABILITY_POINTER | CDK_SEAT_CAPABILITY_TOUCH, |
1122 | TRUE(!(0)), NULL((void*)0), NULL((void*)0), |
1123 | prepare_popup_func, completion); |
1124 | |
1125 | completion->priv->has_grab = TRUE(!(0)); |
1126 | } |
1127 | } |
1128 | |
1129 | void |
1130 | _ctk_entry_completion_popdown (CtkEntryCompletion *completion) |
1131 | { |
1132 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
1133 | return; |
1134 | |
1135 | completion->priv->ignore_enter = FALSE(0); |
1136 | |
1137 | if (completion->priv->has_grab) |
1138 | { |
1139 | cdk_seat_ungrab (cdk_device_get_seat (completion->priv->device)); |
1140 | ctk_grab_remove (completion->priv->popup_window); |
1141 | completion->priv->has_grab = FALSE(0); |
1142 | } |
1143 | |
1144 | ctk_widget_hide (completion->priv->popup_window); |
1145 | } |
1146 | |
1147 | /* public API */ |
1148 | |
1149 | /** |
1150 | * ctk_entry_completion_new: |
1151 | * |
1152 | * Creates a new #CtkEntryCompletion object. |
1153 | * |
1154 | * Returns: A newly created #CtkEntryCompletion object |
1155 | * |
1156 | * Since: 2.4 |
1157 | */ |
1158 | CtkEntryCompletion * |
1159 | ctk_entry_completion_new (void) |
1160 | { |
1161 | CtkEntryCompletion *completion; |
1162 | |
1163 | completion = g_object_new (CTK_TYPE_ENTRY_COMPLETION(ctk_entry_completion_get_type ()), NULL((void*)0)); |
1164 | |
1165 | return completion; |
1166 | } |
1167 | |
1168 | /** |
1169 | * ctk_entry_completion_new_with_area: |
1170 | * @area: the #CtkCellArea used to layout cells |
1171 | * |
1172 | * Creates a new #CtkEntryCompletion object using the |
1173 | * specified @area to layout cells in the underlying |
1174 | * #CtkTreeViewColumn for the drop-down menu. |
1175 | * |
1176 | * Returns: A newly created #CtkEntryCompletion object |
1177 | * |
1178 | * Since: 3.0 |
1179 | */ |
1180 | CtkEntryCompletion * |
1181 | ctk_entry_completion_new_with_area (CtkCellArea *area) |
1182 | { |
1183 | CtkEntryCompletion *completion; |
1184 | |
1185 | completion = g_object_new (CTK_TYPE_ENTRY_COMPLETION(ctk_entry_completion_get_type ()), "cell-area", area, NULL((void*)0)); |
1186 | |
1187 | return completion; |
1188 | } |
1189 | |
1190 | /** |
1191 | * ctk_entry_completion_get_entry: |
1192 | * @completion: a #CtkEntryCompletion |
1193 | * |
1194 | * Gets the entry @completion has been attached to. |
1195 | * |
1196 | * Returns: (transfer none): The entry @completion has been attached to |
1197 | * |
1198 | * Since: 2.4 |
1199 | */ |
1200 | CtkWidget * |
1201 | ctk_entry_completion_get_entry (CtkEntryCompletion *completion) |
1202 | { |
1203 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return (((void*)0)); } } while (0); |
1204 | |
1205 | return completion->priv->entry; |
1206 | } |
1207 | |
1208 | /** |
1209 | * ctk_entry_completion_set_model: |
1210 | * @completion: a #CtkEntryCompletion |
1211 | * @model: (allow-none): the #CtkTreeModel |
1212 | * |
1213 | * Sets the model for a #CtkEntryCompletion. If @completion already has |
1214 | * a model set, it will remove it before setting the new model. |
1215 | * If model is %NULL, then it will unset the model. |
1216 | * |
1217 | * Since: 2.4 |
1218 | */ |
1219 | void |
1220 | ctk_entry_completion_set_model (CtkEntryCompletion *completion, |
1221 | CtkTreeModel *model) |
1222 | { |
1223 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1224 | g_return_if_fail (model == NULL || CTK_IS_TREE_MODEL (model))do { if ((model == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((model)); GType __t = ((ctk_tree_model_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "model == NULL || CTK_IS_TREE_MODEL (model)" ); return; } } while (0); |
1225 | |
1226 | if (!model) |
1227 | { |
1228 | ctk_tree_view_set_model (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))), |
1229 | NULL((void*)0)); |
1230 | _ctk_entry_completion_popdown (completion); |
1231 | completion->priv->filter_model = NULL((void*)0); |
1232 | return; |
1233 | } |
1234 | |
1235 | /* code will unref the old filter model (if any) */ |
1236 | completion->priv->filter_model = |
1237 | CTK_TREE_MODEL_FILTER (ctk_tree_model_filter_new (model, NULL))((((CtkTreeModelFilter*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((ctk_tree_model_filter_new (model, ((void*) 0)))), ((ctk_tree_model_filter_get_type ())))))); |
1238 | ctk_tree_model_filter_set_visible_func (completion->priv->filter_model, |
1239 | ctk_entry_completion_visible_func, |
1240 | completion, |
1241 | NULL((void*)0)); |
1242 | |
1243 | ctk_tree_view_set_model (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))), |
1244 | CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ()))))))); |
1245 | g_object_unref (completion->priv->filter_model); |
1246 | |
1247 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_MODEL]); |
1248 | |
1249 | if (ctk_widget_get_visible (completion->priv->popup_window)) |
1250 | _ctk_entry_completion_resize_popup (completion); |
1251 | } |
1252 | |
1253 | /** |
1254 | * ctk_entry_completion_get_model: |
1255 | * @completion: a #CtkEntryCompletion |
1256 | * |
1257 | * Returns the model the #CtkEntryCompletion is using as data source. |
1258 | * Returns %NULL if the model is unset. |
1259 | * |
1260 | * Returns: (nullable) (transfer none): A #CtkTreeModel, or %NULL if none |
1261 | * is currently being used |
1262 | * |
1263 | * Since: 2.4 |
1264 | */ |
1265 | CtkTreeModel * |
1266 | ctk_entry_completion_get_model (CtkEntryCompletion *completion) |
1267 | { |
1268 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return (((void*)0)); } } while (0); |
1269 | |
1270 | if (!completion->priv->filter_model) |
1271 | return NULL((void*)0); |
1272 | |
1273 | return ctk_tree_model_filter_get_model (completion->priv->filter_model); |
1274 | } |
1275 | |
1276 | /** |
1277 | * ctk_entry_completion_set_match_func: |
1278 | * @completion: a #CtkEntryCompletion |
1279 | * @func: the #CtkEntryCompletionMatchFunc to use |
1280 | * @func_data: user data for @func |
1281 | * @func_notify: destroy notify for @func_data. |
1282 | * |
1283 | * Sets the match function for @completion to be @func. The match function |
1284 | * is used to determine if a row should or should not be in the completion |
1285 | * list. |
1286 | * |
1287 | * Since: 2.4 |
1288 | */ |
1289 | void |
1290 | ctk_entry_completion_set_match_func (CtkEntryCompletion *completion, |
1291 | CtkEntryCompletionMatchFunc func, |
1292 | gpointer func_data, |
1293 | GDestroyNotify func_notify) |
1294 | { |
1295 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1296 | |
1297 | if (completion->priv->match_notify) |
1298 | (* completion->priv->match_notify) (completion->priv->match_data); |
1299 | |
1300 | completion->priv->match_func = func; |
1301 | completion->priv->match_data = func_data; |
1302 | completion->priv->match_notify = func_notify; |
1303 | } |
1304 | |
1305 | /** |
1306 | * ctk_entry_completion_set_minimum_key_length: |
1307 | * @completion: a #CtkEntryCompletion |
1308 | * @length: the minimum length of the key in order to start completing |
1309 | * |
1310 | * Requires the length of the search key for @completion to be at least |
1311 | * @length. This is useful for long lists, where completing using a small |
1312 | * key takes a lot of time and will come up with meaningless results anyway |
1313 | * (ie, a too large dataset). |
1314 | * |
1315 | * Since: 2.4 |
1316 | */ |
1317 | void |
1318 | ctk_entry_completion_set_minimum_key_length (CtkEntryCompletion *completion, |
1319 | gint length) |
1320 | { |
1321 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1322 | g_return_if_fail (length >= 0)do { if ((length >= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "length >= 0"); return ; } } while (0); |
1323 | |
1324 | if (completion->priv->minimum_key_length != length) |
1325 | { |
1326 | completion->priv->minimum_key_length = length; |
1327 | |
1328 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), |
1329 | entry_completion_props[PROP_MINIMUM_KEY_LENGTH]); |
1330 | } |
1331 | } |
1332 | |
1333 | /** |
1334 | * ctk_entry_completion_get_minimum_key_length: |
1335 | * @completion: a #CtkEntryCompletion |
1336 | * |
1337 | * Returns the minimum key length as set for @completion. |
1338 | * |
1339 | * Returns: The currently used minimum key length |
1340 | * |
1341 | * Since: 2.4 |
1342 | */ |
1343 | gint |
1344 | ctk_entry_completion_get_minimum_key_length (CtkEntryCompletion *completion) |
1345 | { |
1346 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return (0); } } while (0); |
1347 | |
1348 | return completion->priv->minimum_key_length; |
1349 | } |
1350 | |
1351 | /** |
1352 | * ctk_entry_completion_complete: |
1353 | * @completion: a #CtkEntryCompletion |
1354 | * |
1355 | * Requests a completion operation, or in other words a refiltering of the |
1356 | * current list with completions, using the current key. The completion list |
1357 | * view will be updated accordingly. |
1358 | * |
1359 | * Since: 2.4 |
1360 | */ |
1361 | void |
1362 | ctk_entry_completion_complete (CtkEntryCompletion *completion) |
1363 | { |
1364 | gchar *tmp; |
1365 | CtkTreeIter iter; |
1366 | |
1367 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1368 | g_return_if_fail (CTK_IS_ENTRY (completion->priv->entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion->priv->entry)); GType __t = ((ctk_entry_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY (completion->priv->entry)" ); return; } } while (0); |
1369 | |
1370 | if (completion->priv->filter_model) |
1371 | { |
1372 | gint matches; |
1373 | gint actions; |
1374 | gboolean popup_single; |
1375 | |
1376 | g_free (completion->priv->case_normalized_key); |
1377 | |
1378 | tmp = g_utf8_normalize (ctk_entry_get_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () ))))))), |
1379 | -1, G_NORMALIZE_ALL); |
1380 | completion->priv->case_normalized_key = g_utf8_casefold (tmp, -1); |
1381 | g_free (tmp); |
1382 | |
1383 | ctk_tree_model_filter_refilter (completion->priv->filter_model); |
1384 | |
1385 | if (!ctk_tree_model_get_iter_first (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), &iter)) |
1386 | g_signal_emit (completion, entry_completion_signals[NO_MATCHES], 0); |
1387 | |
1388 | if (ctk_widget_get_visible (completion->priv->popup_window)) |
1389 | _ctk_entry_completion_resize_popup (completion); |
1390 | |
1391 | matches = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
1392 | actions = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->actions)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->actions)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
1393 | |
1394 | g_object_get (completion, "popup-single-match", &popup_single, NULL((void*)0)); |
1395 | if ((matches > (popup_single ? 0: 1)) || actions > 0) |
1396 | { |
1397 | if (ctk_widget_get_visible (completion->priv->popup_window)) |
1398 | _ctk_entry_completion_resize_popup (completion); |
1399 | else |
1400 | ctk_entry_completion_popup (completion); |
1401 | } |
1402 | else |
1403 | _ctk_entry_completion_popdown (completion); |
1404 | } |
1405 | else if (ctk_widget_get_visible (completion->priv->popup_window)) |
1406 | _ctk_entry_completion_popdown (completion); |
1407 | |
1408 | } |
1409 | |
1410 | static void |
1411 | ctk_entry_completion_insert_action (CtkEntryCompletion *completion, |
1412 | gint index, |
1413 | const gchar *string, |
1414 | gboolean markup) |
1415 | { |
1416 | CtkTreeIter iter; |
1417 | |
1418 | ctk_list_store_insert (completion->priv->actions, &iter, index); |
1419 | ctk_list_store_set (completion->priv->actions, &iter, |
1420 | 0, string, |
1421 | 1, markup, |
1422 | -1); |
1423 | |
1424 | if (!ctk_widget_get_parent (completion->priv->action_view)) |
1425 | { |
1426 | CtkTreePath *path = ctk_tree_path_new_from_indices (0, -1); |
1427 | |
1428 | ctk_tree_view_set_cursor (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))), |
1429 | path, NULL((void*)0), FALSE(0)); |
1430 | ctk_tree_path_free (path); |
1431 | |
1432 | ctk_box_pack_start (CTK_BOX (completion->priv->vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->vbox)), ((ctk_box_get_type ()))) ))), |
1433 | completion->priv->action_view, FALSE(0), FALSE(0), 0); |
1434 | ctk_widget_show (completion->priv->action_view); |
1435 | } |
1436 | } |
1437 | |
1438 | /** |
1439 | * ctk_entry_completion_insert_action_text: |
1440 | * @completion: a #CtkEntryCompletion |
1441 | * @index_: the index of the item to insert |
1442 | * @text: text of the item to insert |
1443 | * |
1444 | * Inserts an action in @completion’s action item list at position @index_ |
1445 | * with text @text. If you want the action item to have markup, use |
1446 | * ctk_entry_completion_insert_action_markup(). |
1447 | * |
1448 | * Note that @index_ is a relative position in the list of actions and |
1449 | * the position of an action can change when deleting a different action. |
1450 | * |
1451 | * Since: 2.4 |
1452 | */ |
1453 | void |
1454 | ctk_entry_completion_insert_action_text (CtkEntryCompletion *completion, |
1455 | gint index_, |
1456 | const gchar *text) |
1457 | { |
1458 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1459 | g_return_if_fail (text != NULL)do { if ((text != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "text != NULL"); return; } } while (0); |
1460 | |
1461 | ctk_entry_completion_insert_action (completion, index_, text, FALSE(0)); |
1462 | } |
1463 | |
1464 | /** |
1465 | * ctk_entry_completion_insert_action_markup: |
1466 | * @completion: a #CtkEntryCompletion |
1467 | * @index_: the index of the item to insert |
1468 | * @markup: markup of the item to insert |
1469 | * |
1470 | * Inserts an action in @completion’s action item list at position @index_ |
1471 | * with markup @markup. |
1472 | * |
1473 | * Since: 2.4 |
1474 | */ |
1475 | void |
1476 | ctk_entry_completion_insert_action_markup (CtkEntryCompletion *completion, |
1477 | gint index_, |
1478 | const gchar *markup) |
1479 | { |
1480 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1481 | g_return_if_fail (markup != NULL)do { if ((markup != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "markup != NULL"); return ; } } while (0); |
1482 | |
1483 | ctk_entry_completion_insert_action (completion, index_, markup, TRUE(!(0))); |
1484 | } |
1485 | |
1486 | /** |
1487 | * ctk_entry_completion_delete_action: |
1488 | * @completion: a #CtkEntryCompletion |
1489 | * @index_: the index of the item to delete |
1490 | * |
1491 | * Deletes the action at @index_ from @completion’s action list. |
1492 | * |
1493 | * Note that @index_ is a relative position and the position of an |
1494 | * action may have changed since it was inserted. |
1495 | * |
1496 | * Since: 2.4 |
1497 | */ |
1498 | void |
1499 | ctk_entry_completion_delete_action (CtkEntryCompletion *completion, |
1500 | gint index_) |
1501 | { |
1502 | CtkTreeIter iter; |
1503 | |
1504 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1505 | g_return_if_fail (index_ >= 0)do { if ((index_ >= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "index_ >= 0"); return ; } } while (0); |
1506 | |
1507 | ctk_tree_model_iter_nth_child (CTK_TREE_MODEL (completion->priv->actions)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->actions)), ((ctk_tree_model_get_type ())))))), |
1508 | &iter, NULL((void*)0), index_); |
1509 | ctk_list_store_remove (completion->priv->actions, &iter); |
1510 | } |
1511 | |
1512 | /** |
1513 | * ctk_entry_completion_set_text_column: |
1514 | * @completion: a #CtkEntryCompletion |
1515 | * @column: the column in the model of @completion to get strings from |
1516 | * |
1517 | * Convenience function for setting up the most used case of this code: a |
1518 | * completion list with just strings. This function will set up @completion |
1519 | * to have a list displaying all (and just) strings in the completion list, |
1520 | * and to get those strings from @column in the model of @completion. |
1521 | * |
1522 | * This functions creates and adds a #CtkCellRendererText for the selected |
1523 | * column. If you need to set the text column, but don't want the cell |
1524 | * renderer, use g_object_set() to set the #CtkEntryCompletion:text-column |
1525 | * property directly. |
1526 | * |
1527 | * Since: 2.4 |
1528 | */ |
1529 | void |
1530 | ctk_entry_completion_set_text_column (CtkEntryCompletion *completion, |
1531 | gint column) |
1532 | { |
1533 | CtkCellRenderer *cell; |
1534 | |
1535 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1536 | g_return_if_fail (column >= 0)do { if ((column >= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column >= 0"); return ; } } while (0); |
1537 | |
1538 | if (completion->priv->text_column == column) |
1539 | return; |
1540 | |
1541 | completion->priv->text_column = column; |
1542 | |
1543 | cell = ctk_cell_renderer_text_new (); |
1544 | ctk_cell_layout_pack_start (CTK_CELL_LAYOUT (completion)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_cell_layout_get_type ())))))), |
1545 | cell, TRUE(!(0))); |
1546 | ctk_cell_layout_add_attribute (CTK_CELL_LAYOUT (completion)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_cell_layout_get_type ())))))), |
1547 | cell, |
1548 | "text", column); |
1549 | |
1550 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_TEXT_COLUMN]); |
1551 | } |
1552 | |
1553 | /** |
1554 | * ctk_entry_completion_get_text_column: |
1555 | * @completion: a #CtkEntryCompletion |
1556 | * |
1557 | * Returns the column in the model of @completion to get strings from. |
1558 | * |
1559 | * Returns: the column containing the strings |
1560 | * |
1561 | * Since: 2.6 |
1562 | */ |
1563 | gint |
1564 | ctk_entry_completion_get_text_column (CtkEntryCompletion *completion) |
1565 | { |
1566 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return (-1); } } while (0); |
1567 | |
1568 | return completion->priv->text_column; |
1569 | } |
1570 | |
1571 | /* private */ |
1572 | |
1573 | static gboolean |
1574 | ctk_entry_completion_list_enter_notify (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
1575 | CdkEventCrossing *event G_GNUC_UNUSED__attribute__ ((__unused__)), |
1576 | gpointer data) |
1577 | { |
1578 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((data)), ((ctk_entry_completion_get_type () )))))); |
1579 | |
1580 | return completion->priv->ignore_enter; |
1581 | } |
1582 | |
1583 | static gboolean |
1584 | ctk_entry_completion_list_motion_notify (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
1585 | CdkEventMotion *event G_GNUC_UNUSED__attribute__ ((__unused__)), |
1586 | gpointer data) |
1587 | { |
1588 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((data)), ((ctk_entry_completion_get_type () )))))); |
1589 | |
1590 | completion->priv->ignore_enter = FALSE(0); |
1591 | |
1592 | return FALSE(0); |
1593 | } |
1594 | |
1595 | |
1596 | /* some nasty size requisition */ |
1597 | void |
1598 | _ctk_entry_completion_resize_popup (CtkEntryCompletion *completion) |
1599 | { |
1600 | CtkAllocation allocation; |
1601 | gint x, y; |
1602 | gint matches, actions, items, height; |
1603 | CdkDisplay *display; |
1604 | CdkMonitor *monitor; |
1605 | gint vertical_separator; |
1606 | CdkRectangle area; |
1607 | CdkWindow *window; |
1608 | CtkRequisition popup_req; |
1609 | CtkRequisition entry_req; |
1610 | CtkRequisition tree_req; |
1611 | CtkTreePath *path; |
1612 | gboolean above; |
1613 | gint width; |
1614 | CtkTreeViewColumn *action_column; |
1615 | gint action_height; |
1616 | |
1617 | window = ctk_widget_get_window (completion->priv->entry); |
1618 | |
1619 | if (!window) |
1620 | return; |
1621 | |
1622 | if (!completion->priv->filter_model) |
1623 | return; |
1624 | |
1625 | ctk_widget_get_allocation (completion->priv->entry, &allocation); |
1626 | ctk_widget_get_preferred_size (completion->priv->entry, |
1627 | &entry_req, NULL((void*)0)); |
1628 | |
1629 | cdk_window_get_origin (window, &x, &y); |
1630 | x += allocation.x; |
1631 | y += allocation.y + (allocation.height - entry_req.height) / 2; |
1632 | |
1633 | matches = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
1634 | actions = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->actions)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->actions)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
1635 | action_column = ctk_tree_view_get_column (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))), 0); |
1636 | |
1637 | /* Call get preferred size on the on the tree view to force it to validate its |
1638 | * cells before calling into the cell size functions. |
1639 | */ |
1640 | ctk_widget_get_preferred_size (completion->priv->tree_view, |
1641 | &tree_req, NULL((void*)0)); |
1642 | ctk_tree_view_column_cell_get_size (completion->priv->column, NULL((void*)0), |
1643 | NULL((void*)0), NULL((void*)0), NULL((void*)0), &height); |
1644 | ctk_tree_view_column_cell_get_size (action_column, NULL((void*)0), |
1645 | NULL((void*)0), NULL((void*)0), NULL((void*)0), &action_height); |
1646 | |
1647 | ctk_widget_style_get (CTK_WIDGET (completion->priv->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_widget_get_type ())))))), |
1648 | "vertical-separator", &vertical_separator, |
1649 | NULL((void*)0)); |
1650 | |
1651 | height += vertical_separator; |
1652 | |
1653 | ctk_widget_realize (completion->priv->tree_view); |
1654 | |
1655 | display = ctk_widget_get_display (CTK_WIDGET (completion->priv->entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_widget_get_type ( )))))))); |
1656 | monitor = cdk_display_get_monitor_at_window (display, window); |
1657 | cdk_monitor_get_workarea (monitor, &area); |
1658 | |
1659 | if (height == 0) |
1660 | items = 0; |
1661 | else if (y > area.height / 2) |
1662 | items = MIN (matches, (((area.y + y) - (actions * action_height)) / height) - 1)(((matches) < ((((area.y + y) - (actions * action_height)) / height) - 1)) ? (matches) : ((((area.y + y) - (actions * action_height )) / height) - 1)); |
1663 | else |
1664 | items = MIN (matches, (((area.height - y) - (actions * action_height)) / height) - 1)(((matches) < ((((area.height - y) - (actions * action_height )) / height) - 1)) ? (matches) : ((((area.height - y) - (actions * action_height)) / height) - 1)); |
1665 | |
1666 | if (items <= 0) |
1667 | ctk_widget_hide (completion->priv->scrolled_window); |
1668 | else |
1669 | ctk_widget_show (completion->priv->scrolled_window); |
1670 | |
1671 | if (completion->priv->popup_set_width) |
1672 | width = MIN (allocation.width, area.width)(((allocation.width) < (area.width)) ? (allocation.width) : (area.width)); |
1673 | else |
1674 | width = -1; |
1675 | |
1676 | ctk_tree_view_columns_autosize (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ()))))))); |
1677 | ctk_scrolled_window_set_min_content_width (CTK_SCROLLED_WINDOW (completion->priv->scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((completion->priv->scrolled_window)), ((ctk_scrolled_window_get_type ())))))), width); |
1678 | ctk_widget_set_size_request (completion->priv->popup_window, width, -1); |
1679 | ctk_scrolled_window_set_min_content_height (CTK_SCROLLED_WINDOW (completion->priv->scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((completion->priv->scrolled_window)), ((ctk_scrolled_window_get_type ())))))), items * height); |
1680 | |
1681 | if (actions) |
1682 | ctk_widget_show (completion->priv->action_view); |
1683 | else |
1684 | ctk_widget_hide (completion->priv->action_view); |
1685 | |
1686 | ctk_widget_get_preferred_size (completion->priv->popup_window, |
1687 | &popup_req, NULL((void*)0)); |
1688 | |
1689 | if (x < area.x) |
1690 | x = area.x; |
1691 | else if (x + popup_req.width > area.x + area.width) |
1692 | x = area.x + area.width - popup_req.width; |
1693 | |
1694 | if (y + entry_req.height + popup_req.height <= area.y + area.height || |
1695 | y - area.y < (area.y + area.height) - (y + entry_req.height)) |
1696 | { |
1697 | y += entry_req.height; |
1698 | above = FALSE(0); |
1699 | } |
1700 | else |
1701 | { |
1702 | y -= popup_req.height; |
1703 | above = TRUE(!(0)); |
1704 | } |
1705 | |
1706 | if (matches > 0) |
1707 | { |
1708 | path = ctk_tree_path_new_from_indices (above ? matches - 1 : 0, -1); |
1709 | ctk_tree_view_scroll_to_cell (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))), path, |
1710 | NULL((void*)0), FALSE(0), 0.0, 0.0); |
1711 | ctk_tree_path_free (path); |
1712 | } |
1713 | |
1714 | ctk_window_move (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), x, y); |
1715 | } |
1716 | |
1717 | static gboolean |
1718 | ctk_entry_completion_match_selected (CtkEntryCompletion *completion, |
1719 | CtkTreeModel *model, |
1720 | CtkTreeIter *iter) |
1721 | { |
1722 | gchar *str = NULL((void*)0); |
1723 | |
1724 | ctk_tree_model_get (model, iter, completion->priv->text_column, &str, -1); |
1725 | ctk_entry_set_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))), str ? str : ""); |
1726 | |
1727 | /* move cursor to the end */ |
1728 | ctk_editable_set_position (CTK_EDITABLE (completion->priv->entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_editable_get_type ())))))), -1); |
1729 | |
1730 | g_free (str); |
1731 | |
1732 | return TRUE(!(0)); |
1733 | } |
1734 | |
1735 | static gboolean |
1736 | ctk_entry_completion_cursor_on_match (CtkEntryCompletion *completion, |
1737 | CtkTreeModel *model, |
1738 | CtkTreeIter *iter) |
1739 | { |
1740 | ctk_entry_completion_insert_completion (completion, model, iter); |
1741 | |
1742 | return TRUE(!(0)); |
1743 | } |
1744 | |
1745 | /** |
1746 | * ctk_entry_completion_compute_prefix: |
1747 | * @completion: the entry completion |
1748 | * @key: The text to complete for |
1749 | * |
1750 | * Computes the common prefix that is shared by all rows in @completion |
1751 | * that start with @key. If no row matches @key, %NULL will be returned. |
1752 | * Note that a text column must have been set for this function to work, |
1753 | * see ctk_entry_completion_set_text_column() for details. |
1754 | * |
1755 | * Returns: (nullable) (transfer full): The common prefix all rows starting with |
1756 | * @key or %NULL if no row matches @key. |
1757 | * |
1758 | * Since: 3.4 |
1759 | **/ |
1760 | gchar * |
1761 | ctk_entry_completion_compute_prefix (CtkEntryCompletion *completion, |
1762 | const char *key) |
1763 | { |
1764 | CtkTreeIter iter; |
1765 | gchar *prefix = NULL((void*)0); |
1766 | gboolean valid; |
1767 | |
1768 | if (completion->priv->text_column < 0) |
1769 | return NULL((void*)0); |
1770 | |
1771 | valid = ctk_tree_model_get_iter_first (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), |
1772 | &iter); |
1773 | |
1774 | while (valid) |
1775 | { |
1776 | gchar *text; |
1777 | |
1778 | ctk_tree_model_get (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), |
1779 | &iter, completion->priv->text_column, &text, |
1780 | -1); |
1781 | |
1782 | if (text && g_str_has_prefix (text, key)(__builtin_constant_p (key)? __extension__ ({ const char * const __str = (text); const char * const __prefix = (key); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (text, key) )) |
1783 | { |
1784 | if (!prefix) |
1785 | prefix = g_strdup (text)g_strdup_inline (text); |
1786 | else |
1787 | { |
1788 | gchar *p = prefix; |
1789 | gchar *q = text; |
1790 | |
1791 | while (*p && *p == *q) |
1792 | { |
1793 | p++; |
1794 | q++; |
1795 | } |
1796 | |
1797 | *p = '\0'; |
1798 | |
1799 | if (p > prefix) |
1800 | { |
1801 | /* strip a partial multibyte character */ |
1802 | q = g_utf8_find_prev_char (prefix, p); |
1803 | switch (g_utf8_get_char_validated (q, p - q)) |
1804 | { |
1805 | case (gunichar)-2: |
1806 | case (gunichar)-1: |
1807 | *q = 0; |
1808 | default: ; |
1809 | } |
1810 | } |
1811 | } |
1812 | } |
1813 | |
1814 | g_free (text); |
1815 | valid = ctk_tree_model_iter_next (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), |
1816 | &iter); |
1817 | } |
1818 | |
1819 | return prefix; |
1820 | } |
1821 | |
1822 | |
1823 | static gboolean |
1824 | ctk_entry_completion_real_insert_prefix (CtkEntryCompletion *completion, |
1825 | const gchar *prefix) |
1826 | { |
1827 | if (prefix) |
1828 | { |
1829 | gint key_len; |
1830 | gint prefix_len; |
1831 | const gchar *key; |
1832 | |
1833 | prefix_len = g_utf8_strlen (prefix, -1); |
1834 | |
1835 | key = ctk_entry_get_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () ))))))); |
1836 | key_len = g_utf8_strlen (key, -1); |
1837 | |
1838 | if (prefix_len > key_len) |
1839 | { |
1840 | gint pos = prefix_len; |
1841 | |
1842 | ctk_editable_insert_text (CTK_EDITABLE (completion->priv->entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_editable_get_type ())))))), |
1843 | prefix + strlen (key), -1, &pos); |
1844 | ctk_editable_select_region (CTK_EDITABLE (completion->priv->entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_editable_get_type ())))))), |
1845 | key_len, prefix_len); |
1846 | |
1847 | completion->priv->has_completion = TRUE(!(0)); |
1848 | } |
1849 | } |
1850 | |
1851 | return TRUE(!(0)); |
1852 | } |
1853 | |
1854 | /** |
1855 | * ctk_entry_completion_get_completion_prefix: |
1856 | * @completion: a #CtkEntryCompletion |
1857 | * |
1858 | * Get the original text entered by the user that triggered |
1859 | * the completion or %NULL if there’s no completion ongoing. |
1860 | * |
1861 | * Returns: the prefix for the current completion |
1862 | * |
1863 | * Since: 2.12 |
1864 | */ |
1865 | const gchar* |
1866 | ctk_entry_completion_get_completion_prefix (CtkEntryCompletion *completion) |
1867 | { |
1868 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return (((void*)0)); } } while (0); |
1869 | |
1870 | return completion->priv->completion_prefix; |
1871 | } |
1872 | |
1873 | static void |
1874 | ctk_entry_completion_insert_completion_text (CtkEntryCompletion *completion, |
1875 | const gchar *text) |
1876 | { |
1877 | CtkEntryCompletionPrivate *priv = completion->priv; |
Value stored to 'priv' during its initialization is never read | |
1878 | gint len; |
1879 | |
1880 | priv = completion->priv; |
1881 | |
1882 | if (priv->changed_id > 0) |
1883 | g_signal_handler_block (priv->entry, priv->changed_id); |
1884 | |
1885 | if (priv->insert_text_id > 0) |
1886 | g_signal_handler_block (priv->entry, priv->insert_text_id); |
1887 | |
1888 | ctk_entry_set_text (CTK_ENTRY (priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->entry)), ((ctk_entry_get_type ())))))), text); |
1889 | |
1890 | len = strlen (priv->completion_prefix); |
1891 | ctk_editable_select_region (CTK_EDITABLE (priv->entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->entry)), ((ctk_editable_get_type ())))))), len, -1); |
1892 | |
1893 | if (priv->changed_id > 0) |
1894 | g_signal_handler_unblock (priv->entry, priv->changed_id); |
1895 | |
1896 | if (priv->insert_text_id > 0) |
1897 | g_signal_handler_unblock (priv->entry, priv->insert_text_id); |
1898 | } |
1899 | |
1900 | static gboolean |
1901 | ctk_entry_completion_insert_completion (CtkEntryCompletion *completion, |
1902 | CtkTreeModel *model, |
1903 | CtkTreeIter *iter) |
1904 | { |
1905 | gchar *str = NULL((void*)0); |
1906 | |
1907 | if (completion->priv->text_column < 0) |
1908 | return FALSE(0); |
1909 | |
1910 | ctk_tree_model_get (model, iter, |
1911 | completion->priv->text_column, &str, |
1912 | -1); |
1913 | |
1914 | ctk_entry_completion_insert_completion_text (completion, str); |
1915 | |
1916 | g_free (str); |
1917 | |
1918 | return TRUE(!(0)); |
1919 | } |
1920 | |
1921 | /** |
1922 | * ctk_entry_completion_insert_prefix: |
1923 | * @completion: a #CtkEntryCompletion |
1924 | * |
1925 | * Requests a prefix insertion. |
1926 | * |
1927 | * Since: 2.6 |
1928 | */ |
1929 | void |
1930 | ctk_entry_completion_insert_prefix (CtkEntryCompletion *completion) |
1931 | { |
1932 | gboolean done; |
1933 | gchar *prefix; |
1934 | |
1935 | if (completion->priv->insert_text_id > 0) |
1936 | g_signal_handler_block (completion->priv->entry, |
1937 | completion->priv->insert_text_id); |
1938 | |
1939 | prefix = ctk_entry_completion_compute_prefix (completion, |
1940 | ctk_entry_get_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))))); |
1941 | |
1942 | if (prefix) |
1943 | { |
1944 | g_signal_emit (completion, entry_completion_signals[INSERT_PREFIX], |
1945 | 0, prefix, &done); |
1946 | g_free (prefix); |
1947 | } |
1948 | |
1949 | if (completion->priv->insert_text_id > 0) |
1950 | g_signal_handler_unblock (completion->priv->entry, |
1951 | completion->priv->insert_text_id); |
1952 | } |
1953 | |
1954 | /** |
1955 | * ctk_entry_completion_set_inline_completion: |
1956 | * @completion: a #CtkEntryCompletion |
1957 | * @inline_completion: %TRUE to do inline completion |
1958 | * |
1959 | * Sets whether the common prefix of the possible completions should |
1960 | * be automatically inserted in the entry. |
1961 | * |
1962 | * Since: 2.6 |
1963 | */ |
1964 | void |
1965 | ctk_entry_completion_set_inline_completion (CtkEntryCompletion *completion, |
1966 | gboolean inline_completion) |
1967 | { |
1968 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
1969 | |
1970 | inline_completion = inline_completion != FALSE(0); |
1971 | |
1972 | if (completion->priv->inline_completion != inline_completion) |
1973 | { |
1974 | completion->priv->inline_completion = inline_completion; |
1975 | |
1976 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_INLINE_COMPLETION]); |
1977 | } |
1978 | } |
1979 | |
1980 | /** |
1981 | * ctk_entry_completion_get_inline_completion: |
1982 | * @completion: a #CtkEntryCompletion |
1983 | * |
1984 | * Returns whether the common prefix of the possible completions should |
1985 | * be automatically inserted in the entry. |
1986 | * |
1987 | * Returns: %TRUE if inline completion is turned on |
1988 | * |
1989 | * Since: 2.6 |
1990 | */ |
1991 | gboolean |
1992 | ctk_entry_completion_get_inline_completion (CtkEntryCompletion *completion) |
1993 | { |
1994 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return ((0)); } } while (0); |
1995 | |
1996 | return completion->priv->inline_completion; |
1997 | } |
1998 | |
1999 | /** |
2000 | * ctk_entry_completion_set_popup_completion: |
2001 | * @completion: a #CtkEntryCompletion |
2002 | * @popup_completion: %TRUE to do popup completion |
2003 | * |
2004 | * Sets whether the completions should be presented in a popup window. |
2005 | * |
2006 | * Since: 2.6 |
2007 | */ |
2008 | void |
2009 | ctk_entry_completion_set_popup_completion (CtkEntryCompletion *completion, |
2010 | gboolean popup_completion) |
2011 | { |
2012 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
2013 | |
2014 | popup_completion = popup_completion != FALSE(0); |
2015 | |
2016 | if (completion->priv->popup_completion != popup_completion) |
2017 | { |
2018 | completion->priv->popup_completion = popup_completion; |
2019 | |
2020 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_POPUP_COMPLETION]); |
2021 | } |
2022 | } |
2023 | |
2024 | |
2025 | /** |
2026 | * ctk_entry_completion_get_popup_completion: |
2027 | * @completion: a #CtkEntryCompletion |
2028 | * |
2029 | * Returns whether the completions should be presented in a popup window. |
2030 | * |
2031 | * Returns: %TRUE if popup completion is turned on |
2032 | * |
2033 | * Since: 2.6 |
2034 | */ |
2035 | gboolean |
2036 | ctk_entry_completion_get_popup_completion (CtkEntryCompletion *completion) |
2037 | { |
2038 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return ((!(0))); } } while (0); |
2039 | |
2040 | return completion->priv->popup_completion; |
2041 | } |
2042 | |
2043 | /** |
2044 | * ctk_entry_completion_set_popup_set_width: |
2045 | * @completion: a #CtkEntryCompletion |
2046 | * @popup_set_width: %TRUE to make the width of the popup the same as the entry |
2047 | * |
2048 | * Sets whether the completion popup window will be resized to be the same |
2049 | * width as the entry. |
2050 | * |
2051 | * Since: 2.8 |
2052 | */ |
2053 | void |
2054 | ctk_entry_completion_set_popup_set_width (CtkEntryCompletion *completion, |
2055 | gboolean popup_set_width) |
2056 | { |
2057 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
2058 | |
2059 | popup_set_width = popup_set_width != FALSE(0); |
2060 | |
2061 | if (completion->priv->popup_set_width != popup_set_width) |
2062 | { |
2063 | completion->priv->popup_set_width = popup_set_width; |
2064 | |
2065 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_POPUP_SET_WIDTH]); |
2066 | } |
2067 | } |
2068 | |
2069 | /** |
2070 | * ctk_entry_completion_get_popup_set_width: |
2071 | * @completion: a #CtkEntryCompletion |
2072 | * |
2073 | * Returns whether the completion popup window will be resized to the |
2074 | * width of the entry. |
2075 | * |
2076 | * Returns: %TRUE if the popup window will be resized to the width of |
2077 | * the entry |
2078 | * |
2079 | * Since: 2.8 |
2080 | */ |
2081 | gboolean |
2082 | ctk_entry_completion_get_popup_set_width (CtkEntryCompletion *completion) |
2083 | { |
2084 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return ((!(0))); } } while (0); |
2085 | |
2086 | return completion->priv->popup_set_width; |
2087 | } |
2088 | |
2089 | |
2090 | /** |
2091 | * ctk_entry_completion_set_popup_single_match: |
2092 | * @completion: a #CtkEntryCompletion |
2093 | * @popup_single_match: %TRUE if the popup should appear even for a single |
2094 | * match |
2095 | * |
2096 | * Sets whether the completion popup window will appear even if there is |
2097 | * only a single match. You may want to set this to %FALSE if you |
2098 | * are using [inline completion][CtkEntryCompletion--inline-completion]. |
2099 | * |
2100 | * Since: 2.8 |
2101 | */ |
2102 | void |
2103 | ctk_entry_completion_set_popup_single_match (CtkEntryCompletion *completion, |
2104 | gboolean popup_single_match) |
2105 | { |
2106 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
2107 | |
2108 | popup_single_match = popup_single_match != FALSE(0); |
2109 | |
2110 | if (completion->priv->popup_single_match != popup_single_match) |
2111 | { |
2112 | completion->priv->popup_single_match = popup_single_match; |
2113 | |
2114 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_POPUP_SINGLE_MATCH]); |
2115 | } |
2116 | } |
2117 | |
2118 | /** |
2119 | * ctk_entry_completion_get_popup_single_match: |
2120 | * @completion: a #CtkEntryCompletion |
2121 | * |
2122 | * Returns whether the completion popup window will appear even if there is |
2123 | * only a single match. |
2124 | * |
2125 | * Returns: %TRUE if the popup window will appear regardless of the |
2126 | * number of matches |
2127 | * |
2128 | * Since: 2.8 |
2129 | */ |
2130 | gboolean |
2131 | ctk_entry_completion_get_popup_single_match (CtkEntryCompletion *completion) |
2132 | { |
2133 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return ((!(0))); } } while (0); |
2134 | |
2135 | return completion->priv->popup_single_match; |
2136 | } |
2137 | |
2138 | /** |
2139 | * ctk_entry_completion_set_inline_selection: |
2140 | * @completion: a #CtkEntryCompletion |
2141 | * @inline_selection: %TRUE to do inline selection |
2142 | * |
2143 | * Sets whether it is possible to cycle through the possible completions |
2144 | * inside the entry. |
2145 | * |
2146 | * Since: 2.12 |
2147 | */ |
2148 | void |
2149 | ctk_entry_completion_set_inline_selection (CtkEntryCompletion *completion, |
2150 | gboolean inline_selection) |
2151 | { |
2152 | g_return_if_fail (CTK_IS_ENTRY_COMPLETION (completion))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return; } } while (0); |
2153 | |
2154 | inline_selection = inline_selection != FALSE(0); |
2155 | |
2156 | if (completion->priv->inline_selection != inline_selection) |
2157 | { |
2158 | completion->priv->inline_selection = inline_selection; |
2159 | |
2160 | g_object_notify_by_pspec (G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))), entry_completion_props[PROP_INLINE_SELECTION]); |
2161 | } |
2162 | } |
2163 | |
2164 | /** |
2165 | * ctk_entry_completion_get_inline_selection: |
2166 | * @completion: a #CtkEntryCompletion |
2167 | * |
2168 | * Returns %TRUE if inline-selection mode is turned on. |
2169 | * |
2170 | * Returns: %TRUE if inline-selection mode is on |
2171 | * |
2172 | * Since: 2.12 |
2173 | */ |
2174 | gboolean |
2175 | ctk_entry_completion_get_inline_selection (CtkEntryCompletion *completion) |
2176 | { |
2177 | g_return_val_if_fail (CTK_IS_ENTRY_COMPLETION (completion), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((completion)); GType __t = ((ctk_entry_completion_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ENTRY_COMPLETION (completion)"); return ((0)); } } while (0); |
2178 | |
2179 | return completion->priv->inline_selection; |
2180 | } |
2181 | |
2182 | |
2183 | static gint |
2184 | ctk_entry_completion_timeout (gpointer data) |
2185 | { |
2186 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((data)), ((ctk_entry_completion_get_type () )))))); |
2187 | |
2188 | completion->priv->completion_timeout = 0; |
2189 | |
2190 | if (completion->priv->filter_model && |
2191 | g_utf8_strlen (ctk_entry_get_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () ))))))), -1) |
2192 | >= completion->priv->minimum_key_length) |
2193 | { |
2194 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))))); |
2195 | ctk_entry_completion_complete (completion); |
2196 | } |
2197 | else if (ctk_widget_get_visible (completion->priv->popup_window)) |
2198 | _ctk_entry_completion_popdown (completion); |
2199 | |
2200 | return FALSE(0); |
2201 | } |
2202 | |
2203 | static inline gboolean |
2204 | keyval_is_cursor_move (guint keyval) |
2205 | { |
2206 | if (keyval == CDK_KEY_Up0xff52 || keyval == CDK_KEY_KP_Up0xff97) |
2207 | return TRUE(!(0)); |
2208 | |
2209 | if (keyval == CDK_KEY_Down0xff54 || keyval == CDK_KEY_KP_Down0xff99) |
2210 | return TRUE(!(0)); |
2211 | |
2212 | if (keyval == CDK_KEY_Page_Up0xff55) |
2213 | return TRUE(!(0)); |
2214 | |
2215 | if (keyval == CDK_KEY_Page_Down0xff56) |
2216 | return TRUE(!(0)); |
2217 | |
2218 | return FALSE(0); |
2219 | } |
2220 | |
2221 | static gboolean |
2222 | ctk_entry_completion_key_press (CtkWidget *widget, |
2223 | CdkEventKey *event, |
2224 | gpointer user_data) |
2225 | { |
2226 | gint matches, actions = 0; |
2227 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
2228 | |
2229 | if (!completion->priv->popup_completion) |
2230 | return FALSE(0); |
2231 | |
2232 | if (event->keyval == CDK_KEY_Return0xff0d || |
2233 | event->keyval == CDK_KEY_KP_Enter0xff8d || |
2234 | event->keyval == CDK_KEY_ISO_Enter0xfe34 || |
2235 | event->keyval == CDK_KEY_Escape0xff1b) |
2236 | { |
2237 | if (completion->priv->completion_timeout) |
2238 | { |
2239 | g_source_remove (completion->priv->completion_timeout); |
2240 | completion->priv->completion_timeout = 0; |
2241 | } |
2242 | } |
2243 | |
2244 | if (!ctk_widget_get_mapped (completion->priv->popup_window)) |
2245 | return FALSE(0); |
2246 | |
2247 | matches = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->filter_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->filter_model)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
2248 | |
2249 | if (completion->priv->actions) |
2250 | actions = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (completion->priv->actions)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->actions)), ((ctk_tree_model_get_type ())))))), NULL((void*)0)); |
2251 | |
2252 | if (keyval_is_cursor_move (event->keyval)) |
2253 | { |
2254 | CtkTreePath *path = NULL((void*)0); |
2255 | |
2256 | if (event->keyval == CDK_KEY_Up0xff52 || event->keyval == CDK_KEY_KP_Up0xff97) |
2257 | { |
2258 | if (completion->priv->current_selected < 0) |
2259 | completion->priv->current_selected = matches + actions - 1; |
2260 | else |
2261 | completion->priv->current_selected--; |
2262 | } |
2263 | else if (event->keyval == CDK_KEY_Down0xff54 || event->keyval == CDK_KEY_KP_Down0xff99) |
2264 | { |
2265 | if (completion->priv->current_selected < matches + actions - 1) |
2266 | completion->priv->current_selected++; |
2267 | else |
2268 | completion->priv->current_selected = -1; |
2269 | } |
2270 | else if (event->keyval == CDK_KEY_Page_Up0xff55) |
2271 | { |
2272 | if (completion->priv->current_selected < 0) |
2273 | completion->priv->current_selected = matches + actions - 1; |
2274 | else if (completion->priv->current_selected == 0) |
2275 | completion->priv->current_selected = -1; |
2276 | else if (completion->priv->current_selected < matches) |
2277 | { |
2278 | completion->priv->current_selected -= PAGE_STEP14; |
2279 | if (completion->priv->current_selected < 0) |
2280 | completion->priv->current_selected = 0; |
2281 | } |
2282 | else |
2283 | { |
2284 | completion->priv->current_selected -= PAGE_STEP14; |
2285 | if (completion->priv->current_selected < matches - 1) |
2286 | completion->priv->current_selected = matches - 1; |
2287 | } |
2288 | } |
2289 | else if (event->keyval == CDK_KEY_Page_Down0xff56) |
2290 | { |
2291 | if (completion->priv->current_selected < 0) |
2292 | completion->priv->current_selected = 0; |
2293 | else if (completion->priv->current_selected < matches - 1) |
2294 | { |
2295 | completion->priv->current_selected += PAGE_STEP14; |
2296 | if (completion->priv->current_selected > matches - 1) |
2297 | completion->priv->current_selected = matches - 1; |
2298 | } |
2299 | else if (completion->priv->current_selected == matches + actions - 1) |
2300 | { |
2301 | completion->priv->current_selected = -1; |
2302 | } |
2303 | else |
2304 | { |
2305 | completion->priv->current_selected += PAGE_STEP14; |
2306 | if (completion->priv->current_selected > matches + actions - 1) |
2307 | completion->priv->current_selected = matches + actions - 1; |
2308 | } |
2309 | } |
2310 | |
2311 | if (completion->priv->current_selected < 0) |
2312 | { |
2313 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))))); |
2314 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))))); |
2315 | |
2316 | if (completion->priv->inline_selection && |
2317 | completion->priv->completion_prefix) |
2318 | { |
2319 | ctk_entry_set_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))), |
2320 | completion->priv->completion_prefix); |
2321 | ctk_editable_set_position (CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_editable_get_type ())))))), -1); |
2322 | } |
2323 | } |
2324 | else if (completion->priv->current_selected < matches) |
2325 | { |
2326 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))))); |
2327 | |
2328 | path = ctk_tree_path_new_from_indices (completion->priv->current_selected, -1); |
2329 | ctk_tree_view_set_cursor (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))), |
2330 | path, NULL((void*)0), FALSE(0)); |
2331 | |
2332 | if (completion->priv->inline_selection) |
2333 | { |
2334 | |
2335 | CtkTreeIter iter; |
2336 | CtkTreeIter child_iter; |
2337 | CtkTreeModel *model = NULL((void*)0); |
2338 | CtkTreeSelection *sel; |
2339 | gboolean entry_set; |
2340 | |
2341 | sel = ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ()))))))); |
2342 | if (!ctk_tree_selection_get_selected (sel, &model, &iter)) |
2343 | return FALSE(0); |
2344 | ctk_tree_model_filter_convert_iter_to_child_iter (CTK_TREE_MODEL_FILTER (model)((((CtkTreeModelFilter*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_model_filter_get_type ( ))))))), &child_iter, &iter); |
2345 | model = ctk_tree_model_filter_get_model (CTK_TREE_MODEL_FILTER (model)((((CtkTreeModelFilter*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_model_filter_get_type ( )))))))); |
2346 | |
2347 | if (completion->priv->completion_prefix == NULL((void*)0)) |
2348 | completion->priv->completion_prefix = g_strdup (ctk_entry_get_text (CTK_ENTRY (completion->priv->entry)))g_strdup_inline (ctk_entry_get_text (((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((completion->priv->entry)), ((ctk_entry_get_type ())))))))); |
2349 | |
2350 | g_signal_emit_by_name (completion, "cursor-on-match", model, |
2351 | &child_iter, &entry_set); |
2352 | } |
2353 | } |
2354 | else if (completion->priv->current_selected - matches >= 0) |
2355 | { |
2356 | ctk_tree_selection_unselect_all (ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ())))))))); |
2357 | |
2358 | path = ctk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1); |
2359 | ctk_tree_view_set_cursor (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ())))))), |
2360 | path, NULL((void*)0), FALSE(0)); |
2361 | |
2362 | if (completion->priv->inline_selection && |
2363 | completion->priv->completion_prefix) |
2364 | { |
2365 | ctk_entry_set_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))), |
2366 | completion->priv->completion_prefix); |
2367 | ctk_editable_set_position (CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_editable_get_type ())))))), -1); |
2368 | } |
2369 | } |
2370 | |
2371 | ctk_tree_path_free (path); |
2372 | |
2373 | return TRUE(!(0)); |
2374 | } |
2375 | else if (event->keyval == CDK_KEY_Escape0xff1b || |
2376 | event->keyval == CDK_KEY_Left0xff51 || |
2377 | event->keyval == CDK_KEY_KP_Left0xff96 || |
2378 | event->keyval == CDK_KEY_Right0xff53 || |
2379 | event->keyval == CDK_KEY_KP_Right0xff98) |
2380 | { |
2381 | gboolean retval = TRUE(!(0)); |
2382 | |
2383 | ctk_entry_reset_im_context (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_entry_get_type ()))))))); |
2384 | _ctk_entry_completion_popdown (completion); |
2385 | |
2386 | if (completion->priv->current_selected < 0) |
2387 | { |
2388 | retval = FALSE(0); |
2389 | goto keypress_completion_out; |
2390 | } |
2391 | else if (completion->priv->inline_selection) |
2392 | { |
2393 | /* Escape rejects the tentative completion */ |
2394 | if (event->keyval == CDK_KEY_Escape0xff1b) |
2395 | { |
2396 | if (completion->priv->completion_prefix) |
2397 | ctk_entry_set_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))), |
2398 | completion->priv->completion_prefix); |
2399 | else |
2400 | ctk_entry_set_text (CTK_ENTRY (completion->priv->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->entry)), ((ctk_entry_get_type () )))))), ""); |
2401 | } |
2402 | |
2403 | /* Move the cursor to the end for Right/Esc */ |
2404 | if (event->keyval == CDK_KEY_Right0xff53 || |
2405 | event->keyval == CDK_KEY_KP_Right0xff98 || |
2406 | event->keyval == CDK_KEY_Escape0xff1b) |
2407 | ctk_editable_set_position (CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_editable_get_type ())))))), -1); |
2408 | /* Let the default keybindings run for Left, i.e. either move to the |
2409 | * * previous character or select word if a modifier is used */ |
2410 | else |
2411 | retval = FALSE(0); |
2412 | } |
2413 | |
2414 | keypress_completion_out: |
2415 | if (completion->priv->inline_selection) |
2416 | { |
2417 | g_free (completion->priv->completion_prefix); |
2418 | completion->priv->completion_prefix = NULL((void*)0); |
2419 | } |
2420 | |
2421 | return retval; |
2422 | } |
2423 | else if (event->keyval == CDK_KEY_Tab0xff09 || |
2424 | event->keyval == CDK_KEY_KP_Tab0xff89 || |
2425 | event->keyval == CDK_KEY_ISO_Left_Tab0xfe20) |
2426 | { |
2427 | ctk_entry_reset_im_context (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_entry_get_type ()))))))); |
2428 | _ctk_entry_completion_popdown (completion); |
2429 | |
2430 | g_free (completion->priv->completion_prefix); |
2431 | completion->priv->completion_prefix = NULL((void*)0); |
2432 | |
2433 | return FALSE(0); |
2434 | } |
2435 | else if (event->keyval == CDK_KEY_ISO_Enter0xfe34 || |
2436 | event->keyval == CDK_KEY_KP_Enter0xff8d || |
2437 | event->keyval == CDK_KEY_Return0xff0d) |
2438 | { |
2439 | CtkTreeIter iter; |
2440 | CtkTreeModel *model = NULL((void*)0); |
2441 | CtkTreeModel *child_model; |
2442 | CtkTreeIter child_iter; |
2443 | CtkTreeSelection *sel; |
2444 | gboolean retval = TRUE(!(0)); |
2445 | |
2446 | ctk_entry_reset_im_context (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_entry_get_type ()))))))); |
2447 | _ctk_entry_completion_popdown (completion); |
2448 | |
2449 | if (completion->priv->current_selected < matches) |
2450 | { |
2451 | gboolean entry_set; |
2452 | |
2453 | sel = ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->tree_view)), ((ctk_tree_view_get_type ()))))))); |
2454 | if (ctk_tree_selection_get_selected (sel, &model, &iter)) |
2455 | { |
2456 | ctk_tree_model_filter_convert_iter_to_child_iter (CTK_TREE_MODEL_FILTER (model)((((CtkTreeModelFilter*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_model_filter_get_type ( ))))))), &child_iter, &iter); |
2457 | child_model = ctk_tree_model_filter_get_model (CTK_TREE_MODEL_FILTER (model)((((CtkTreeModelFilter*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_model_filter_get_type ( )))))))); |
2458 | g_signal_handler_block (widget, completion->priv->changed_id); |
2459 | g_signal_emit_by_name (completion, "match-selected", |
2460 | child_model, &child_iter, &entry_set); |
2461 | g_signal_handler_unblock (widget, completion->priv->changed_id); |
2462 | |
2463 | if (!entry_set) |
2464 | { |
2465 | gchar *str = NULL((void*)0); |
2466 | |
2467 | ctk_tree_model_get (model, &iter, |
2468 | completion->priv->text_column, &str, |
2469 | -1); |
2470 | |
2471 | ctk_entry_set_text (CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_entry_get_type ())))))), str); |
2472 | |
2473 | /* move the cursor to the end */ |
2474 | ctk_editable_set_position (CTK_EDITABLE (widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_editable_get_type ())))))), -1); |
2475 | g_free (str); |
2476 | } |
2477 | } |
2478 | else |
2479 | retval = FALSE(0); |
2480 | } |
2481 | else if (completion->priv->current_selected - matches >= 0) |
2482 | { |
2483 | sel = ctk_tree_view_get_selection (CTK_TREE_VIEW (completion->priv->action_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->action_view)), ((ctk_tree_view_get_type ()))))))); |
2484 | if (ctk_tree_selection_get_selected (sel, &model, &iter)) |
2485 | { |
2486 | CtkTreePath *path; |
2487 | |
2488 | path = ctk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1); |
2489 | g_signal_emit_by_name (completion, "action-activated", |
2490 | ctk_tree_path_get_indices (path)[0]); |
2491 | ctk_tree_path_free (path); |
2492 | } |
2493 | else |
2494 | retval = FALSE(0); |
2495 | } |
2496 | |
2497 | g_free (completion->priv->completion_prefix); |
2498 | completion->priv->completion_prefix = NULL((void*)0); |
2499 | |
2500 | return retval; |
2501 | } |
2502 | |
2503 | return FALSE(0); |
2504 | } |
2505 | |
2506 | static void |
2507 | ctk_entry_completion_changed (CtkWidget *widget, |
2508 | gpointer user_data) |
2509 | { |
2510 | CtkEntryCompletion *completion = CTK_ENTRY_COMPLETION (user_data)((((CtkEntryCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_entry_completion_get_type ())))))); |
2511 | CtkEntry *entry = CTK_ENTRY (widget)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_entry_get_type ())))))); |
2512 | CdkDevice *device; |
2513 | |
2514 | if (!completion->priv->popup_completion) |
2515 | return; |
2516 | |
2517 | /* (re)install completion timeout */ |
2518 | if (completion->priv->completion_timeout) |
2519 | { |
2520 | g_source_remove (completion->priv->completion_timeout); |
2521 | completion->priv->completion_timeout = 0; |
2522 | } |
2523 | |
2524 | if (!ctk_entry_get_text (entry)) |
2525 | return; |
2526 | |
2527 | /* no need to normalize for this test */ |
2528 | if (completion->priv->minimum_key_length > 0 && |
2529 | strcmp ("", ctk_entry_get_text (entry)) == 0) |
2530 | { |
2531 | if (ctk_widget_get_visible (completion->priv->popup_window)) |
2532 | _ctk_entry_completion_popdown (completion); |
2533 | return; |
2534 | } |
2535 | |
2536 | device = ctk_get_current_event_device (); |
2537 | |
2538 | if (device && cdk_device_get_source (device) == CDK_SOURCE_KEYBOARD) |
2539 | device = cdk_device_get_associated_device (device); |
2540 | |
2541 | if (device) |
2542 | completion->priv->device = device; |
2543 | |
2544 | completion->priv->completion_timeout = |
2545 | cdk_threads_add_timeout (COMPLETION_TIMEOUT100, |
2546 | ctk_entry_completion_timeout, |
2547 | completion); |
2548 | g_source_set_name_by_id (completion->priv->completion_timeout, "[ctk+] ctk_entry_completion_timeout"); |
2549 | } |
2550 | |
2551 | static gboolean |
2552 | check_completion_callback (CtkEntryCompletion *completion) |
2553 | { |
2554 | completion->priv->check_completion_idle = NULL((void*)0); |
2555 | |
2556 | ctk_entry_completion_complete (completion); |
2557 | ctk_entry_completion_insert_prefix (completion); |
2558 | |
2559 | return FALSE(0); |
2560 | } |
2561 | |
2562 | static void |
2563 | clear_completion_callback (CtkEntry *entry, |
2564 | GParamSpec *pspec) |
2565 | { |
2566 | CtkEntryCompletion *completion = ctk_entry_get_completion (entry); |
2567 | |
2568 | if (!completion->priv->inline_completion) |
2569 | return; |
2570 | |
2571 | if (pspec->name == I_("cursor-position")g_intern_static_string ("cursor-position") || |
2572 | pspec->name == I_("selection-bound")g_intern_static_string ("selection-bound")) |
2573 | completion->priv->has_completion = FALSE(0); |
2574 | } |
2575 | |
2576 | static gboolean |
2577 | accept_completion_callback (CtkEntry *entry) |
2578 | { |
2579 | CtkEntryCompletion *completion = ctk_entry_get_completion (entry); |
2580 | |
2581 | if (!completion->priv->inline_completion) |
2582 | return FALSE(0); |
2583 | |
2584 | if (completion->priv->has_completion) |
2585 | ctk_editable_set_position (CTK_EDITABLE (entry)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_editable_get_type ())))))), |
2586 | ctk_entry_buffer_get_length (ctk_entry_get_buffer (entry))); |
2587 | |
2588 | return FALSE(0); |
2589 | } |
2590 | |
2591 | static void |
2592 | completion_insert_text_callback (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)), |
2593 | const gchar *text G_GNUC_UNUSED__attribute__ ((__unused__)), |
2594 | gint length G_GNUC_UNUSED__attribute__ ((__unused__)), |
2595 | gint position G_GNUC_UNUSED__attribute__ ((__unused__)), |
2596 | CtkEntryCompletion *completion) |
2597 | { |
2598 | if (!completion->priv->inline_completion) |
2599 | return; |
2600 | |
2601 | /* idle to update the selection based on the file list */ |
2602 | if (completion->priv->check_completion_idle == NULL((void*)0)) |
2603 | { |
2604 | completion->priv->check_completion_idle = g_idle_source_new (); |
2605 | g_source_set_priority (completion->priv->check_completion_idle, G_PRIORITY_HIGH-100); |
2606 | g_source_set_closure (completion->priv->check_completion_idle, |
2607 | g_cclosure_new_object (G_CALLBACK (check_completion_callback)((GCallback) (check_completion_callback)), |
2608 | G_OBJECT (completion)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), (((GType) ((20) << (2)))))))))); |
2609 | g_source_attach (completion->priv->check_completion_idle, NULL((void*)0)); |
2610 | } |
2611 | } |
2612 | |
2613 | static void |
2614 | connect_completion_signals (CtkEntryCompletion *completion) |
2615 | { |
2616 | completion->priv->changed_id = |
2617 | g_signal_connect (completion->priv->entry, "changed",g_signal_connect_data ((completion->priv->entry), ("changed" ), (((GCallback) (ctk_entry_completion_changed))), (completion ), ((void*)0), (GConnectFlags) 0) |
2618 | G_CALLBACK (ctk_entry_completion_changed), completion)g_signal_connect_data ((completion->priv->entry), ("changed" ), (((GCallback) (ctk_entry_completion_changed))), (completion ), ((void*)0), (GConnectFlags) 0); |
2619 | g_signal_connect (completion->priv->entry, "key-press-event",g_signal_connect_data ((completion->priv->entry), ("key-press-event" ), (((GCallback) (ctk_entry_completion_key_press))), (completion ), ((void*)0), (GConnectFlags) 0) |
2620 | G_CALLBACK (ctk_entry_completion_key_press), completion)g_signal_connect_data ((completion->priv->entry), ("key-press-event" ), (((GCallback) (ctk_entry_completion_key_press))), (completion ), ((void*)0), (GConnectFlags) 0); |
2621 | |
2622 | completion->priv->insert_text_id = |
2623 | g_signal_connect (completion->priv->entry, "insert-text",g_signal_connect_data ((completion->priv->entry), ("insert-text" ), (((GCallback) (completion_insert_text_callback))), (completion ), ((void*)0), (GConnectFlags) 0) |
2624 | G_CALLBACK (completion_insert_text_callback), completion)g_signal_connect_data ((completion->priv->entry), ("insert-text" ), (((GCallback) (completion_insert_text_callback))), (completion ), ((void*)0), (GConnectFlags) 0); |
2625 | g_signal_connect (completion->priv->entry, "notify",g_signal_connect_data ((completion->priv->entry), ("notify" ), (((GCallback) (clear_completion_callback))), (completion), ((void*)0), (GConnectFlags) 0) |
2626 | G_CALLBACK (clear_completion_callback), completion)g_signal_connect_data ((completion->priv->entry), ("notify" ), (((GCallback) (clear_completion_callback))), (completion), ((void*)0), (GConnectFlags) 0); |
2627 | g_signal_connect (completion->priv->entry, "activate",g_signal_connect_data ((completion->priv->entry), ("activate" ), (((GCallback) (accept_completion_callback))), (completion) , ((void*)0), (GConnectFlags) 0) |
2628 | G_CALLBACK (accept_completion_callback), completion)g_signal_connect_data ((completion->priv->entry), ("activate" ), (((GCallback) (accept_completion_callback))), (completion) , ((void*)0), (GConnectFlags) 0); |
2629 | g_signal_connect (completion->priv->entry, "focus-out-event",g_signal_connect_data ((completion->priv->entry), ("focus-out-event" ), (((GCallback) (accept_completion_callback))), (completion) , ((void*)0), (GConnectFlags) 0) |
2630 | G_CALLBACK (accept_completion_callback), completion)g_signal_connect_data ((completion->priv->entry), ("focus-out-event" ), (((GCallback) (accept_completion_callback))), (completion) , ((void*)0), (GConnectFlags) 0); |
2631 | } |
2632 | |
2633 | static void |
2634 | set_accessible_relation (CtkWidget *window, |
2635 | CtkWidget *entry) |
2636 | { |
2637 | AtkObject *window_accessible; |
2638 | AtkObject *entry_accessible; |
2639 | |
2640 | window_accessible = ctk_widget_get_accessible (window); |
2641 | entry_accessible = ctk_widget_get_accessible (entry); |
2642 | |
2643 | atk_object_add_relationship (window_accessible, |
2644 | ATK_RELATION_POPUP_FOR, |
2645 | entry_accessible); |
2646 | } |
2647 | |
2648 | static void |
2649 | unset_accessible_relation (CtkWidget *window, |
2650 | CtkWidget *entry) |
2651 | { |
2652 | AtkObject *window_accessible; |
2653 | AtkObject *entry_accessible; |
2654 | |
2655 | window_accessible = ctk_widget_get_accessible (window); |
2656 | entry_accessible = ctk_widget_get_accessible (entry); |
2657 | |
2658 | atk_object_remove_relationship (window_accessible, |
2659 | ATK_RELATION_POPUP_FOR, |
2660 | entry_accessible); |
2661 | } |
2662 | |
2663 | static void |
2664 | disconnect_completion_signals (CtkEntryCompletion *completion) |
2665 | { |
2666 | if (completion->priv->changed_id > 0 && |
2667 | g_signal_handler_is_connected (completion->priv->entry, |
2668 | completion->priv->changed_id)) |
2669 | { |
2670 | g_signal_handler_disconnect (completion->priv->entry, |
2671 | completion->priv->changed_id); |
2672 | completion->priv->changed_id = 0; |
2673 | } |
2674 | g_signal_handlers_disconnect_by_func (completion->priv->entry,g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_entry_completion_key_press ))), (completion)) |
2675 | G_CALLBACK (ctk_entry_completion_key_press), completion)g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_entry_completion_key_press ))), (completion)); |
2676 | if (completion->priv->insert_text_id > 0 && |
2677 | g_signal_handler_is_connected (completion->priv->entry, |
2678 | completion->priv->insert_text_id)) |
2679 | { |
2680 | g_signal_handler_disconnect (completion->priv->entry, |
2681 | completion->priv->insert_text_id); |
2682 | completion->priv->insert_text_id = 0; |
2683 | } |
2684 | g_signal_handlers_disconnect_by_func (completion->priv->entry,g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (completion_insert_text_callback ))), (completion)) |
2685 | G_CALLBACK (completion_insert_text_callback), completion)g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (completion_insert_text_callback ))), (completion)); |
2686 | g_signal_handlers_disconnect_by_func (completion->priv->entry,g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (clear_completion_callback ))), (completion)) |
2687 | G_CALLBACK (clear_completion_callback), completion)g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (clear_completion_callback ))), (completion)); |
2688 | g_signal_handlers_disconnect_by_func (completion->priv->entry,g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (accept_completion_callback ))), (completion)) |
2689 | G_CALLBACK (accept_completion_callback), completion)g_signal_handlers_disconnect_matched ((completion->priv-> entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (accept_completion_callback ))), (completion)); |
2690 | } |
2691 | |
2692 | void |
2693 | _ctk_entry_completion_disconnect (CtkEntryCompletion *completion) |
2694 | { |
2695 | if (completion->priv->completion_timeout) |
2696 | { |
2697 | g_source_remove (completion->priv->completion_timeout); |
2698 | completion->priv->completion_timeout = 0; |
2699 | } |
2700 | if (completion->priv->check_completion_idle) |
2701 | { |
2702 | g_source_destroy (completion->priv->check_completion_idle); |
2703 | completion->priv->check_completion_idle = NULL((void*)0); |
2704 | } |
2705 | |
2706 | if (ctk_widget_get_mapped (completion->priv->popup_window)) |
2707 | _ctk_entry_completion_popdown (completion); |
2708 | |
2709 | disconnect_completion_signals (completion); |
2710 | |
2711 | unset_accessible_relation (completion->priv->popup_window, |
2712 | completion->priv->entry); |
2713 | ctk_window_set_attached_to (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), |
2714 | NULL((void*)0)); |
2715 | |
2716 | ctk_window_set_transient_for (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), NULL((void*)0)); |
2717 | |
2718 | completion->priv->entry = NULL((void*)0); |
2719 | } |
2720 | |
2721 | void |
2722 | _ctk_entry_completion_connect (CtkEntryCompletion *completion, |
2723 | CtkEntry *entry) |
2724 | { |
2725 | completion->priv->entry = CTK_WIDGET (entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_widget_get_type ())))))); |
2726 | |
2727 | set_accessible_relation (completion->priv->popup_window, |
2728 | completion->priv->entry); |
2729 | ctk_window_set_attached_to (CTK_WINDOW (completion->priv->popup_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->priv->popup_window)), ((ctk_window_get_type ())))))), |
2730 | completion->priv->entry); |
2731 | |
2732 | connect_completion_signals (completion); |
2733 | } |