1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
2 /* gtksourcecompletionprovider.c
3  * This file is part of gtksourcecompletion
4  *
5  * Copyright (C) 2007 -2009 Jesús Barbero Rodríguez <chuchiperriman@gmail.com>
6  * Copyright (C) 2009 - Jesse van den Kieboom <jessevdk@gnome.org>
7  *
8  * gtksourceview is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * gtksourceview is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 
24 /**
25  * SECTION:completionprovider
26  * @title: GtkSourceCompletionProvider
27  * @short_description: Completion provider interface
28  *
29  * You must implement this interface to provide proposals to #GtkSourceCompletion
30  *
31  */
32 
33 #include <gtksourceview/gtksourcecompletionprovider.h>
34 
35 /* Default implementations */
36 static gchar *
gtk_source_completion_provider_get_name_default(GtkSourceCompletionProvider * provider)37 gtk_source_completion_provider_get_name_default (GtkSourceCompletionProvider *provider)
38 {
39 	g_return_val_if_reached (NULL);
40 }
41 
42 static GdkPixbuf *
gtk_source_completion_provider_get_icon_default(GtkSourceCompletionProvider * provider)43 gtk_source_completion_provider_get_icon_default (GtkSourceCompletionProvider *provider)
44 {
45 	return NULL;
46 }
47 
48 static void
gtk_source_completion_provider_populate_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context)49 gtk_source_completion_provider_populate_default (GtkSourceCompletionProvider *provider,
50                                                  GtkSourceCompletionContext  *context)
51 {
52 	gtk_source_completion_context_add_proposals (context, provider, NULL, TRUE);
53 }
54 
55 static GtkSourceCompletionActivation
gtk_source_completion_provider_get_activation_default(GtkSourceCompletionProvider * provider)56 gtk_source_completion_provider_get_activation_default (GtkSourceCompletionProvider *provider)
57 {
58 	return GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE |
59 	       GTK_SOURCE_COMPLETION_ACTIVATION_USER_REQUESTED;
60 }
61 
62 static gboolean
gtk_source_completion_provider_match_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context)63 gtk_source_completion_provider_match_default (GtkSourceCompletionProvider *provider,
64                                               GtkSourceCompletionContext  *context)
65 {
66 	return TRUE;
67 }
68 
69 static GtkWidget *
gtk_source_completion_provider_get_info_widget_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal)70 gtk_source_completion_provider_get_info_widget_default (GtkSourceCompletionProvider *provider,
71                                                         GtkSourceCompletionProposal *proposal)
72 {
73 	return NULL;
74 }
75 
76 static void
gtk_source_completion_provider_update_info_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal,GtkSourceCompletionInfo * info)77 gtk_source_completion_provider_update_info_default (GtkSourceCompletionProvider *provider,
78                                                     GtkSourceCompletionProposal *proposal,
79                                                     GtkSourceCompletionInfo     *info)
80 {
81 }
82 
83 static gboolean
gtk_source_completion_provider_get_start_iter_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context,GtkSourceCompletionProposal * proposal,GtkTextIter * iter)84 gtk_source_completion_provider_get_start_iter_default (GtkSourceCompletionProvider *provider,
85                                                        GtkSourceCompletionContext  *context,
86                                                        GtkSourceCompletionProposal *proposal,
87                                                        GtkTextIter                 *iter)
88 {
89 	return FALSE;
90 }
91 
92 static gboolean
gtk_source_completion_provider_activate_proposal_default(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal,GtkTextIter * iter)93 gtk_source_completion_provider_activate_proposal_default (GtkSourceCompletionProvider *provider,
94                                                           GtkSourceCompletionProposal *proposal,
95                                                           GtkTextIter                 *iter)
96 {
97 	return FALSE;
98 }
99 
100 static gint
gtk_source_completion_provider_get_interactive_delay_default(GtkSourceCompletionProvider * provider)101 gtk_source_completion_provider_get_interactive_delay_default (GtkSourceCompletionProvider *provider)
102 {
103 	/* -1 means the default value in the completion object */
104 	return -1;
105 }
106 
107 static gint
gtk_source_completion_provider_get_priority_default(GtkSourceCompletionProvider * provider)108 gtk_source_completion_provider_get_priority_default (GtkSourceCompletionProvider *provider)
109 {
110 	return 0;
111 }
112 
113 static void
gtk_source_completion_provider_base_init(GtkSourceCompletionProviderIface * iface)114 gtk_source_completion_provider_base_init (GtkSourceCompletionProviderIface *iface)
115 {
116 	static gboolean initialized = FALSE;
117 
118 	iface->get_name = gtk_source_completion_provider_get_name_default;
119 	iface->get_icon = gtk_source_completion_provider_get_icon_default;
120 
121 	iface->populate = gtk_source_completion_provider_populate_default;
122 
123 	iface->match = gtk_source_completion_provider_match_default;
124 	iface->get_activation = gtk_source_completion_provider_get_activation_default;
125 
126 	iface->get_info_widget = gtk_source_completion_provider_get_info_widget_default;
127 	iface->update_info = gtk_source_completion_provider_update_info_default;
128 
129 	iface->get_start_iter = gtk_source_completion_provider_get_start_iter_default;
130 	iface->activate_proposal = gtk_source_completion_provider_activate_proposal_default;
131 
132 	iface->get_interactive_delay = gtk_source_completion_provider_get_interactive_delay_default;
133 	iface->get_priority = gtk_source_completion_provider_get_priority_default;
134 
135 	if (!initialized)
136 	{
137 		initialized = TRUE;
138 	}
139 }
140 
141 GType
gtk_source_completion_provider_get_type()142 gtk_source_completion_provider_get_type ()
143 {
144 	static GType gtk_source_completion_provider_type_id = 0;
145 
146 	if (!gtk_source_completion_provider_type_id)
147 	{
148 		static const GTypeInfo g_define_type_info =
149 		{
150 			sizeof (GtkSourceCompletionProviderIface),
151 			(GBaseInitFunc) gtk_source_completion_provider_base_init,
152 			(GBaseFinalizeFunc) NULL,
153 			(GClassInitFunc) NULL,
154 			(GClassFinalizeFunc) NULL,
155 			NULL,
156 			0,
157 			0,
158 			(GInstanceInitFunc) NULL
159 		};
160 
161 		gtk_source_completion_provider_type_id =
162 				g_type_register_static (G_TYPE_INTERFACE,
163 							"GtkSourceCompletionProvider",
164 							&g_define_type_info,
165 							0);
166 
167 		g_type_interface_add_prerequisite (gtk_source_completion_provider_type_id,
168 		                                   G_TYPE_OBJECT);
169 	}
170 
171 	return gtk_source_completion_provider_type_id;
172 }
173 
174 /**
175  * gtk_source_completion_provider_get_name:
176  * @provider: The #GtkSourceCompletionProvider
177  *
178  * Get the name of the provider. This should be a translatable name for
179  * display to the user. For example: _("Document word completion provider"). The
180  * returned string must be freed with g_free().
181  *
182  * Returns: A new string containing the name of the provider.
183  */
184 gchar *
gtk_source_completion_provider_get_name(GtkSourceCompletionProvider * provider)185 gtk_source_completion_provider_get_name (GtkSourceCompletionProvider *provider)
186 {
187 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), NULL);
188 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_name (provider);
189 }
190 
191 /**
192  * gtk_source_completion_provider_get_icon:
193  * @provider: The #GtkSourceCompletionProvider
194  *
195  * Get the icon of the provider.
196  *
197  * Returns: The icon to be used for the provider, or %NULL if the provider does
198  *          not have a special icon.
199  */
200 GdkPixbuf *
gtk_source_completion_provider_get_icon(GtkSourceCompletionProvider * provider)201 gtk_source_completion_provider_get_icon (GtkSourceCompletionProvider *provider)
202 {
203 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), NULL);
204 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_icon (provider);
205 }
206 
207 /**
208  * gtk_source_completion_provider_populate:
209  * @provider: The #GtkSourceCompletionProvider
210  * @context: The #GtkSourceCompletionContext
211  *
212  * Populate @context with proposals from @provider
213  *
214  */
215 void
gtk_source_completion_provider_populate(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context)216 gtk_source_completion_provider_populate (GtkSourceCompletionProvider *provider,
217                                          GtkSourceCompletionContext  *context)
218 {
219 	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider));
220 	GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->populate (provider, context);
221 }
222 
223 /**
224  * gtk_source_completion_provider_get_activation:
225  * @provider: A #GtkSourceCompletionProvider
226  *
227  * Get with what kind of activation the provider should be activated.
228  *
229  * Returns: a combination of #GtkSourceCompletionActivation.
230  *
231  **/
232 GtkSourceCompletionActivation
gtk_source_completion_provider_get_activation(GtkSourceCompletionProvider * provider)233 gtk_source_completion_provider_get_activation (GtkSourceCompletionProvider *provider)
234 {
235 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), GTK_SOURCE_COMPLETION_ACTIVATION_NONE);
236 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_activation (provider);
237 }
238 
239 /**
240  * gtk_source_completion_provider_match:
241  * @provider: The #GtkSourceCompletionProvider
242  * @context: The #GtkSourceCompletionContext
243  *
244  * Get whether the provider match the context of completion detailed in
245  * @context.
246  *
247  * Returns: %TRUE if @provider matches the completion context, %FALSE otherwise
248  */
249 gboolean
gtk_source_completion_provider_match(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context)250 gtk_source_completion_provider_match (GtkSourceCompletionProvider *provider,
251                                       GtkSourceCompletionContext  *context)
252 {
253 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), TRUE);
254 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->match (provider,
255 	                                                                       context);
256 }
257 
258 /**
259  * gtk_source_completion_provider_get_info_widget:
260  * @provider: The #GtkSourceCompletionProvider
261  * @proposal: The currently selected #GtkSourceCompletionProposal
262  *
263  * Get a customized info widget to show extra information of a proposal.
264  * This allows for customized widgets on a proposal basis, although in general
265  * providers will have the same custom widget for all their proposals and
266  * @proposal can be ignored. The implementation of this function is optional.
267  * If implemented, #gtk_source_completion_provider_update_info MUST also be
268  * implemented. If not implemented, the default
269  * #gtk_source_completion_proposal_get_info will be used to display extra
270  * information about a #GtkSourceCompletionProposal.
271  *
272  * Returns: a custom #GtkWidget to show extra information about @proposal.
273  */
274 GtkWidget *
gtk_source_completion_provider_get_info_widget(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal)275 gtk_source_completion_provider_get_info_widget (GtkSourceCompletionProvider *provider,
276                                                 GtkSourceCompletionProposal *proposal)
277 {
278 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), NULL);
279 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal), NULL);
280 
281 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_info_widget (provider, proposal);
282 }
283 
284 /**
285  * gtk_source_completion_provider_update_info:
286  * @provider: A #GtkSourceCompletionProvider
287  * @proposal: A #GtkSourceCompletionProposal
288  * @info: A #GtkSourceCompletionInfo
289  *
290  * Update extra information shown in @info for @proposal. This should be
291  * implemented if your provider sets a custom info widget for @proposal.
292  * This function MUST be implemented when
293  * #gtk_source_completion_provider_get_info_widget is implemented.
294  */
295 void
gtk_source_completion_provider_update_info(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal,GtkSourceCompletionInfo * info)296 gtk_source_completion_provider_update_info (GtkSourceCompletionProvider *provider,
297                                             GtkSourceCompletionProposal *proposal,
298                                             GtkSourceCompletionInfo     *info)
299 {
300 	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider));
301 	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal));
302 	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_INFO (info));
303 
304 	GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->update_info (provider, proposal, info);
305 }
306 
307 /**
308  * gtk_source_completion_provider_get_start_iter:
309  * @provider: A #GtkSourceCompletionProvider
310  * @proposal: A #GtkSourceCompletionProposal
311  * @context: A #GtkSourceCompletionContext
312  * @iter: A #GtkTextIter
313  *
314  * Get the #GtkTextIter at which the completion for @proposal starts. When
315  * implemented, the completion can use this information to position the
316  * completion window accordingly when a proposal is selected in the completion
317  * window.
318  *
319  * Returns: %TRUE if @iter was set for @proposal, %FALSE otherwise
320  *
321  **/
322 gboolean
gtk_source_completion_provider_get_start_iter(GtkSourceCompletionProvider * provider,GtkSourceCompletionContext * context,GtkSourceCompletionProposal * proposal,GtkTextIter * iter)323 gtk_source_completion_provider_get_start_iter (GtkSourceCompletionProvider *provider,
324                                                GtkSourceCompletionContext  *context,
325                                                GtkSourceCompletionProposal *proposal,
326                                                GtkTextIter                 *iter)
327 {
328 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
329 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_CONTEXT (context), FALSE);
330 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal), FALSE);
331 	g_return_val_if_fail (iter != NULL, FALSE);
332 
333 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_start_iter (provider,
334 	                                                                                context,
335 	                                                                                proposal,
336 	                                                                                iter);
337 }
338 
339 /**
340  * gtk_source_completion_provider_activate_proposal:
341  * @provider: A #GtkSourceCompletionProvider
342  * @proposal: A #GtkSourceCompletionProposal
343  * @iter: A #GtkTextIter
344  *
345  * Activate @proposal at @iter. When this functions returns %FALSE, the default
346  * activation of @proposal will take place which replaces the word at @iter
347  * with the label of @proposal.
348  *
349  * Returns: %TRUE to indicate that the proposal activation has been handled,
350  *          %FALSE otherwise.
351  */
352 gboolean
gtk_source_completion_provider_activate_proposal(GtkSourceCompletionProvider * provider,GtkSourceCompletionProposal * proposal,GtkTextIter * iter)353 gtk_source_completion_provider_activate_proposal (GtkSourceCompletionProvider *provider,
354                                                   GtkSourceCompletionProposal *proposal,
355                                                   GtkTextIter                 *iter)
356 {
357 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
358 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal), FALSE);
359 
360 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->activate_proposal (provider,
361 	                                                                                   proposal,
362 	                                                                                   iter);
363 }
364 
365 /**
366  * gtk_source_completion_provider_get_interactive_delay:
367  * @provider: A # GtkSourceCompletionProvider
368  *
369  * Get the delay in milliseconds before starting interactive completion for
370  * this provider. A value of -1 indicates to use the default value as set
371  * by #GtkSourceCompletion::auto-complete-delay.
372  *
373  * Returns: the interactive delay in milliseconds.
374  *
375  **/
376 gint
gtk_source_completion_provider_get_interactive_delay(GtkSourceCompletionProvider * provider)377 gtk_source_completion_provider_get_interactive_delay (GtkSourceCompletionProvider *provider)
378 {
379 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), -1);
380 
381 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_interactive_delay (provider);
382 }
383 
384 /**
385  * gtk_source_completion_provider_get_priority:
386  * @provider: A # GtkSourceCompletionProvider
387  *
388  * Get the provider priority. The priority determines the order in which
389  * proposals appear in the completion popup. Higher priorities are sorted
390  * before lower priorities. The default priority is 0.
391  *
392  * Returns: the provider priority.
393  *
394  **/
395 gint
gtk_source_completion_provider_get_priority(GtkSourceCompletionProvider * provider)396 gtk_source_completion_provider_get_priority (GtkSourceCompletionProvider *provider)
397 {
398 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), 0);
399 
400 	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_priority (provider);
401 }
402