Bug Summary

File:ctk/ctkentrycompletion.c
Warning:line 1877, column 30
Value stored to 'priv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkentrycompletion.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-171836-43636-1 -x c ctkentrycompletion.c
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 */
96enum
97{
98 INSERT_PREFIX,
99 MATCH_SELECTED,
100 ACTION_ACTIVATED,
101 CURSOR_ON_MATCH,
102 NO_MATCHES,
103 LAST_SIGNAL
104};
105
106/* properties */
107enum
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
123static void ctk_entry_completion_cell_layout_init (CtkCellLayoutIface *iface);
124static CtkCellArea* ctk_entry_completion_get_area (CtkCellLayout *cell_layout);
125
126static void ctk_entry_completion_constructed (GObject *object);
127static void ctk_entry_completion_set_property (GObject *object,
128 guint prop_id,
129 const GValue *value,
130 GParamSpec *pspec);
131static void ctk_entry_completion_get_property (GObject *object,
132 guint prop_id,
133 GValue *value,
134 GParamSpec *pspec);
135static void ctk_entry_completion_finalize (GObject *object);
136static void ctk_entry_completion_dispose (GObject *object);
137
138static gboolean ctk_entry_completion_visible_func (CtkTreeModel *model,
139 CtkTreeIter *iter,
140 gpointer data);
141static gboolean ctk_entry_completion_popup_key_event (CtkWidget *widget,
142 CdkEventKey *event,
143 gpointer user_data);
144static gboolean ctk_entry_completion_popup_button_press (CtkWidget *widget,
145 CdkEventButton *event,
146 gpointer user_data);
147static gboolean ctk_entry_completion_list_button_press (CtkWidget *widget,
148 CdkEventButton *event,
149 gpointer user_data);
150static gboolean ctk_entry_completion_action_button_press (CtkWidget *widget,
151 CdkEventButton *event,
152 gpointer user_data);
153static void ctk_entry_completion_selection_changed (CtkTreeSelection *selection,
154 gpointer data);
155static gboolean ctk_entry_completion_list_enter_notify (CtkWidget *widget,
156 CdkEventCrossing *event,
157 gpointer data);
158static gboolean ctk_entry_completion_list_motion_notify (CtkWidget *widget,
159 CdkEventMotion *event,
160 gpointer data);
161static void ctk_entry_completion_insert_action (CtkEntryCompletion *completion,
162 gint index,
163 const gchar *string,
164 gboolean markup);
165static void ctk_entry_completion_action_data_func (CtkTreeViewColumn *tree_column,
166 CtkCellRenderer *cell,
167 CtkTreeModel *model,
168 CtkTreeIter *iter,
169 gpointer data);
170
171static gboolean ctk_entry_completion_match_selected (CtkEntryCompletion *completion,
172 CtkTreeModel *model,
173 CtkTreeIter *iter);
174static gboolean ctk_entry_completion_real_insert_prefix (CtkEntryCompletion *completion,
175 const gchar *prefix);
176static gboolean ctk_entry_completion_cursor_on_match (CtkEntryCompletion *completion,
177 CtkTreeModel *model,
178 CtkTreeIter *iter);
179static gboolean ctk_entry_completion_insert_completion (CtkEntryCompletion *completion,
180 CtkTreeModel *model,
181 CtkTreeIter *iter);
182static void ctk_entry_completion_insert_completion_text (CtkEntryCompletion *completion,
183 const gchar *text);
184static void connect_completion_signals (CtkEntryCompletion *completion);
185static void disconnect_completion_signals (CtkEntryCompletion *completion);
186
187
188static GParamSpec *entry_completion_props[NUM_PROPERTIES] = { NULL((void*)0), };
189
190static guint entry_completion_signals[LAST_SIGNAL] = { 0 };
191
192/* CtkBuildable */
193static void ctk_entry_completion_buildable_init (CtkBuildableIface *iface);
194
195G_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
203static void
204ctk_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
476static void
477ctk_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
487static void
488ctk_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
495static void
496ctk_entry_completion_cell_layout_init (CtkCellLayoutIface *iface)
497{
498 iface->get_area = ctk_entry_completion_get_area;
499}
500
501static void
502ctk_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
522static void
523ctk_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
643static void
644ctk_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
716static void
717ctk_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
769static void
770ctk_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
784static void
785ctk_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) */
827static CtkCellArea*
828ctk_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 */
844static gboolean
845ctk_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
887static gboolean
888ctk_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
913static gboolean
914ctk_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
929static gboolean
930ctk_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
945static gboolean
946ctk_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
988static gboolean
989ctk_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
1016static void
1017ctk_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
1048static void
1049ctk_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
1062static void
1063prepare_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
1078static void
1079ctk_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
1129void
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 */
1158CtkEntryCompletion *
1159ctk_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 */
1180CtkEntryCompletion *
1181ctk_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 */
1200CtkWidget *
1201ctk_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 */
1219void
1220ctk_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 */
1265CtkTreeModel *
1266ctk_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 */
1289void
1290ctk_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 */
1317void
1318ctk_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 */
1343gint
1344ctk_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 */
1361void
1362ctk_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
1410static void
1411ctk_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 */
1453void
1454ctk_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 */
1475void
1476ctk_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 */
1498void
1499ctk_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 */
1529void
1530ctk_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 */
1563gint
1564ctk_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
1573static gboolean
1574ctk_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
1583static gboolean
1584ctk_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 */
1597void
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
1717static gboolean
1718ctk_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
1735static gboolean
1736ctk_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 **/
1760gchar *
1761ctk_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
1823static gboolean
1824ctk_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 */
1865const gchar*
1866ctk_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
1873static void
1874ctk_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
1900static gboolean
1901ctk_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 */
1929void
1930ctk_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 */
1964void
1965ctk_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 */
1991gboolean
1992ctk_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 */
2008void
2009ctk_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 */
2035gboolean
2036ctk_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 */
2053void
2054ctk_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 */
2081gboolean
2082ctk_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 */
2102void
2103ctk_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 */
2130gboolean
2131ctk_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 */
2148void
2149ctk_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 */
2174gboolean
2175ctk_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
2183static gint
2184ctk_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
2203static inline gboolean
2204keyval_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
2221static gboolean
2222ctk_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
2414keypress_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
2506static void
2507ctk_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
2551static gboolean
2552check_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
2562static void
2563clear_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
2576static gboolean
2577accept_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
2591static void
2592completion_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
2613static void
2614connect_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
2633static void
2634set_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
2648static void
2649unset_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
2663static void
2664disconnect_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
2692void
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
2721void
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}