[gtksourceview/wip/completion-fix: 2/2] CompletionContext: more robust code
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/completion-fix: 2/2] CompletionContext: more robust code
- Date: Fri, 26 Sep 2014 19:56:37 +0000 (UTC)
commit 5d159aa68a2dffdd7a0863706c2b892aad723f94
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Sep 26 21:51:41 2014 +0200
CompletionContext: more robust code
Buffer changes are now handled correctly.
gtk_source_completion_context_get_iter() returns a gboolean to tell if
the iter was set.
Connecting to the mark-set signal is not needed, because the mark can be
set only in set_iter().
gtksourceview/gtksourcecompletioncontext.c | 122 +++++++++++++--------------
gtksourceview/gtksourcecompletioncontext.h | 2 +-
2 files changed, 60 insertions(+), 64 deletions(-)
---
diff --git a/gtksourceview/gtksourcecompletioncontext.c b/gtksourceview/gtksourcecompletioncontext.c
index 202bd9b..723bdf4 100644
--- a/gtksourceview/gtksourcecompletioncontext.c
+++ b/gtksourceview/gtksourcecompletioncontext.c
@@ -95,23 +95,6 @@ guint context_signals[NUM_SIGNALS] = {0,};
G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceCompletionContext, gtk_source_completion_context,
G_TYPE_INITIALLY_UNOWNED)
-/* FIXME: we use this util to get the buffer from the completion
- * but this object is not robust to a change of the buffer associated
- * to the view. Context lifetime should be short enough to not really
- * matter.
- * (swilmet) This can happen when the GtkSourceView is being destroyed:
- * GtkTextView set the buffer to NULL, then the code here calls
- * gtk_text_view_get_buffer() which creates another buffer... So it would be
- * better to handle buffer changes.
- */
-
-static GtkTextBuffer *
-get_buffer (GtkSourceCompletionContext *context)
-{
- GtkSourceView *view = gtk_source_completion_get_view (context->priv->completion);
- return gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-}
-
static void
gtk_source_completion_context_dispose (GObject *object)
{
@@ -136,10 +119,25 @@ gtk_source_completion_context_dispose (GObject *object)
}
static void
-gtk_source_completion_context_set_iter (GtkSourceCompletionContext *context,
- GtkTextIter *iter)
+set_iter (GtkSourceCompletionContext *context,
+ GtkTextIter *iter)
{
- GtkTextBuffer *buffer = get_buffer (context);
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_iter_get_buffer (iter);
+
+ if (context->priv->mark != NULL)
+ {
+ GtkTextBuffer *old_buffer;
+
+ old_buffer = gtk_text_mark_get_buffer (context->priv->mark);
+
+ if (old_buffer != buffer)
+ {
+ g_object_unref (context->priv->mark);
+ context->priv->mark = NULL;
+ }
+ }
if (context->priv->mark == NULL)
{
@@ -150,6 +148,8 @@ gtk_source_completion_context_set_iter (GtkSourceCompletionContext *context,
{
gtk_text_buffer_move_mark (buffer, context->priv->mark, iter);
}
+
+ g_object_notify (G_OBJECT (context), "iter");
}
static void
@@ -165,12 +165,15 @@ gtk_source_completion_context_set_property (GObject *object,
case PROP_COMPLETION:
context->priv->completion = g_value_dup_object (value);
break;
+
case PROP_ITER:
- gtk_source_completion_context_set_iter (context, (GtkTextIter *) g_value_get_boxed
(value));
+ set_iter (context, g_value_get_boxed (value));
break;
+
case PROP_ACTIVATION:
context->priv->activation = g_value_get_flags (value);
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -189,6 +192,7 @@ gtk_source_completion_context_get_property (GObject *object,
case PROP_COMPLETION:
g_value_set_object (value, context->priv->completion);
break;
+
case PROP_ITER:
{
GtkTextIter iter;
@@ -196,51 +200,21 @@ gtk_source_completion_context_get_property (GObject *object,
g_value_set_boxed (value, &iter);
}
break;
+
case PROP_ACTIVATION:
g_value_set_flags (value, context->priv->activation);
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
-buffer_mark_set_cb (GtkTextBuffer *buffer,
- GtkTextIter *iter,
- GtkTextMark *mark,
- GtkSourceCompletionContext *context)
-{
- if (mark == context->priv->mark)
- {
- g_object_notify (G_OBJECT (context), "iter");
- }
-}
-
-static void
-gtk_source_completion_context_constructed (GObject *object)
-{
- GtkSourceCompletionContext *context;
- GtkTextBuffer *buffer;
-
- /* we need to connect after the completion property is set */
- context = GTK_SOURCE_COMPLETION_CONTEXT (object);
- buffer = get_buffer (context);
-
- g_signal_connect_object (buffer,
- "mark-set",
- G_CALLBACK (buffer_mark_set_cb),
- context,
- 0);
-
- G_OBJECT_CLASS (gtk_source_completion_context_parent_class)->constructed (object);
-}
-
-static void
gtk_source_completion_context_class_init (GtkSourceCompletionContextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->constructed = gtk_source_completion_context_constructed;
object_class->set_property = gtk_source_completion_context_set_property;
object_class->get_property = gtk_source_completion_context_get_property;
object_class->dispose = gtk_source_completion_context_dispose;
@@ -345,27 +319,49 @@ gtk_source_completion_context_add_proposals (GtkSourceCompletionContext *contex
*
* Get the iter at which the completion was invoked. Providers can use this
* to determine how and if to match proposals.
+ *
+ * Returns: %TRUE if @iter is correctly set, %FALSE otherwise.
**/
-void
+gboolean
gtk_source_completion_context_get_iter (GtkSourceCompletionContext *context,
GtkTextIter *iter)
{
- GtkTextBuffer *buffer;
-
- g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
+ GtkTextBuffer *mark_buffer;
+ GtkSourceView *view;
+ GtkTextBuffer *completion_buffer;
- buffer = get_buffer (context);
+ g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context), FALSE);
- if (context->priv->mark != NULL)
- {
- gtk_text_buffer_get_iter_at_mark (buffer, iter, context->priv->mark);
- }
- else
+ if (context->priv->mark == NULL)
{
/* This should never happen: context should be always be created
providing a position iter */
g_warning ("Completion context without mark");
+ return FALSE;
+ }
+
+ mark_buffer = gtk_text_mark_get_buffer (context->priv->mark);
+
+ if (mark_buffer == NULL)
+ {
+ return FALSE;
+ }
+
+ view = gtk_source_completion_get_view (context->priv->completion);
+ if (view == NULL)
+ {
+ return FALSE;
}
+
+ completion_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ if (completion_buffer != mark_buffer)
+ {
+ return FALSE;
+ }
+
+ gtk_text_buffer_get_iter_at_mark (mark_buffer, iter, context->priv->mark);
+ return TRUE;
}
/**
diff --git a/gtksourceview/gtksourcecompletioncontext.h b/gtksourceview/gtksourcecompletioncontext.h
index e0e0ce0..ad919c6 100644
--- a/gtksourceview/gtksourcecompletioncontext.h
+++ b/gtksourceview/gtksourcecompletioncontext.h
@@ -78,7 +78,7 @@ void gtk_source_completion_context_add_proposals (GtkSourceCompletionContext
GList *proposals,
gboolean finished);
-void gtk_source_completion_context_get_iter (GtkSourceCompletionContext *context,
+gboolean gtk_source_completion_context_get_iter (GtkSourceCompletionContext *context,
GtkTextIter *iter);
GtkSourceCompletionActivation
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]