|
Packit |
a7d494 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
|
|
Packit |
a7d494 |
/* gtksourcemarkssequence.c
|
|
Packit |
a7d494 |
* This file is part of GtkSourceView
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* Copyright (C) 2013 - Sébastien Wilmet <swilmet@gnome.org>
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* GtkSourceView is free software; you can redistribute it and/or
|
|
Packit |
a7d494 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a7d494 |
* License as published by the Free Software Foundation; either
|
|
Packit |
a7d494 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* GtkSourceView is distributed in the hope that it will be useful,
|
|
Packit |
a7d494 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a7d494 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a7d494 |
* Lesser General Public License for more details.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a7d494 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
a7d494 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
#include "gtksourcemarkssequence.h"
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* An object for storing GtkTextMarks. The text marks are sorted internally with
|
|
Packit |
a7d494 |
* a GSequence. Going to the previous or next text mark has a O(1) complexity.
|
|
Packit |
a7d494 |
* Finding a text mark in the neighborhood of a text iter has a O(log n)
|
|
Packit |
a7d494 |
* complexity, with 'n' the number of marks in the sequence.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* The GSequenceIter associated to a text mark is inserted into the text mark,
|
|
Packit |
a7d494 |
* with g_object_set_qdata(). So the text mark knows its position in the
|
|
Packit |
a7d494 |
* GSequence. This allows to use normal GtkTextMarks in the API, instead of
|
|
Packit |
a7d494 |
* using a subclass or a custom iter.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* The MarksSequence has a weak reference to the text buffer.
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
enum
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
PROP_0,
|
|
Packit |
a7d494 |
PROP_BUFFER,
|
|
Packit |
a7d494 |
};
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
struct _GtkSourceMarksSequencePrivate
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextBuffer *buffer;
|
|
Packit |
a7d494 |
GSequence *seq;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* The quark used for storing the GSequenceIter into the text mark, with
|
|
Packit |
a7d494 |
* g_object_set_qdata().
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
GQuark quark;
|
|
Packit |
a7d494 |
};
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceMarksSequence, _gtk_source_marks_sequence, G_TYPE_OBJECT)
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
remove_qdata (GtkTextMark *mark,
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_object_set_qdata (G_OBJECT (mark),
|
|
Packit |
a7d494 |
seq->priv->quark,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
free_sequence (GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (seq->priv->seq != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_sequence_foreach (seq->priv->seq,
|
|
Packit |
a7d494 |
(GFunc)remove_qdata,
|
|
Packit |
a7d494 |
seq);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_sequence_free (seq->priv->seq);
|
|
Packit |
a7d494 |
seq->priv->seq = NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gint
|
|
Packit |
a7d494 |
compare_marks (GtkTextMark *mark1,
|
|
Packit |
a7d494 |
GtkTextMark *mark2)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextBuffer *buffer;
|
|
Packit |
a7d494 |
GtkTextIter iter1;
|
|
Packit |
a7d494 |
GtkTextIter iter2;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_assert (GTK_IS_TEXT_MARK (mark1));
|
|
Packit |
a7d494 |
g_assert (GTK_IS_TEXT_MARK (mark2));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
buffer = gtk_text_mark_get_buffer (mark1);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_assert (buffer == gtk_text_mark_get_buffer (mark2));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (buffer, &iter1, mark1);
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (buffer, &iter2, mark2);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return gtk_text_iter_compare (&iter1, &iter2);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
mark_set_cb (GtkTextBuffer *buffer,
|
|
Packit |
a7d494 |
GtkTextIter *location,
|
|
Packit |
a7d494 |
GtkTextMark *mark,
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (seq_iter != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_sequence_sort_changed (seq_iter,
|
|
Packit |
a7d494 |
(GCompareDataFunc)compare_marks,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
mark_deleted_cb (GtkTextBuffer *buffer,
|
|
Packit |
a7d494 |
GtkTextMark *mark,
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_remove (seq, mark);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
set_buffer (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextBuffer *buffer)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_assert (seq->priv->buffer == NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq->priv->buffer = buffer;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_object_add_weak_pointer (G_OBJECT (buffer),
|
|
Packit |
a7d494 |
(gpointer *)&seq->priv->buffer);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_signal_connect_object (buffer,
|
|
Packit |
a7d494 |
"mark-set",
|
|
Packit |
a7d494 |
G_CALLBACK (mark_set_cb),
|
|
Packit |
a7d494 |
seq,
|
|
Packit |
a7d494 |
0);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_signal_connect_object (buffer,
|
|
Packit |
a7d494 |
"mark-deleted",
|
|
Packit |
a7d494 |
G_CALLBACK (mark_deleted_cb),
|
|
Packit |
a7d494 |
seq,
|
|
Packit |
a7d494 |
0);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_dispose (GObject *object)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq = GTK_SOURCE_MARKS_SEQUENCE (object);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (seq->priv->buffer != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_object_remove_weak_pointer (G_OBJECT (seq->priv->buffer),
|
|
Packit |
a7d494 |
(gpointer *)&seq->priv->buffer);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq->priv->buffer = NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
free_sequence (seq);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
G_OBJECT_CLASS (_gtk_source_marks_sequence_parent_class)->dispose (object);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_get_property (GObject *object,
|
|
Packit |
a7d494 |
guint prop_id,
|
|
Packit |
a7d494 |
GValue *value,
|
|
Packit |
a7d494 |
GParamSpec *pspec)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (object));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq = GTK_SOURCE_MARKS_SEQUENCE (object);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
switch (prop_id)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
case PROP_BUFFER:
|
|
Packit |
a7d494 |
g_value_set_object (value, seq->priv->buffer);
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
default:
|
|
Packit |
a7d494 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_set_property (GObject *object,
|
|
Packit |
a7d494 |
guint prop_id,
|
|
Packit |
a7d494 |
const GValue *value,
|
|
Packit |
a7d494 |
GParamSpec *pspec)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *seq;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (object));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq = GTK_SOURCE_MARKS_SEQUENCE (object);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
switch (prop_id)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
case PROP_BUFFER:
|
|
Packit |
a7d494 |
set_buffer (seq, g_value_get_object (value));
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
default:
|
|
Packit |
a7d494 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_class_init (GtkSourceMarksSequenceClass *klass)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
object_class->dispose = _gtk_source_marks_sequence_dispose;
|
|
Packit |
a7d494 |
object_class->get_property = _gtk_source_marks_sequence_get_property;
|
|
Packit |
a7d494 |
object_class->set_property = _gtk_source_marks_sequence_set_property;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_object_class_install_property (object_class,
|
|
Packit |
a7d494 |
PROP_BUFFER,
|
|
Packit |
a7d494 |
g_param_spec_object ("buffer",
|
|
Packit |
a7d494 |
"Buffer",
|
|
Packit |
a7d494 |
"The text buffer",
|
|
Packit |
a7d494 |
GTK_TYPE_TEXT_BUFFER,
|
|
Packit |
a7d494 |
G_PARAM_READWRITE |
|
|
Packit |
a7d494 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a7d494 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_init (GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gchar *unique_str;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq->priv = _gtk_source_marks_sequence_get_instance_private (seq);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq->priv->seq = g_sequence_new ((GDestroyNotify)g_object_unref);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
unique_str = g_strdup_printf ("gtk-source-marks-sequence-%p", seq);
|
|
Packit |
a7d494 |
seq->priv->quark = g_quark_from_string (unique_str);
|
|
Packit |
a7d494 |
g_free (unique_str);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GtkSourceMarksSequence *
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_new (GtkTextBuffer *buffer)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_object_new (GTK_SOURCE_TYPE_MARKS_SEQUENCE,
|
|
Packit |
a7d494 |
"buffer", buffer,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gboolean
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_is_empty (GtkSourceMarksSequence *seq)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), TRUE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_sequence_is_empty (seq->priv->seq);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_add (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextMark *mark)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq));
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
|
|
Packit |
a7d494 |
g_return_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (seq_iter != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
/* The mark is already added. */
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_insert_sorted (seq->priv->seq,
|
|
Packit |
a7d494 |
mark,
|
|
Packit |
a7d494 |
(GCompareDataFunc)compare_marks,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_object_ref (mark);
|
|
Packit |
a7d494 |
g_object_set_qdata (G_OBJECT (mark),
|
|
Packit |
a7d494 |
seq->priv->quark,
|
|
Packit |
a7d494 |
seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
void
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_remove (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextMark *mark)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq));
|
|
Packit |
a7d494 |
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (seq_iter != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_object_set_qdata (G_OBJECT (mark), seq->priv->quark, NULL);
|
|
Packit |
a7d494 |
g_sequence_remove (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GtkTextMark *
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_next (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextMark *mark)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (seq_iter != NULL, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_next (seq_iter);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_sequence_iter_is_end (seq_iter) ? NULL : g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GtkTextMark *
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_prev (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextMark *mark)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (seq_iter != NULL, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_begin (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
return NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_prev (seq_iter);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* Moves @iter forward to the next position where there is at least one mark.
|
|
Packit |
a7d494 |
* Returns %TRUE if @iter was moved.
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
gboolean
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_forward_iter (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextIter *iter)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *mark;
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), FALSE);
|
|
Packit |
a7d494 |
g_return_val_if_fail (iter != NULL, FALSE);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == seq->priv->buffer, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
mark = gtk_text_buffer_create_mark (seq->priv->buffer,
|
|
Packit |
a7d494 |
NULL,
|
|
Packit |
a7d494 |
iter,
|
|
Packit |
a7d494 |
TRUE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_search (seq->priv->seq,
|
|
Packit |
a7d494 |
mark,
|
|
Packit |
a7d494 |
(GCompareDataFunc)compare_marks,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_delete_mark (seq->priv->buffer, mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (!g_sequence_iter_is_end (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *cur_mark = g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
GtkTextIter cur_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (gtk_text_iter_compare (iter, &cur_iter) < 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
*iter = cur_iter;
|
|
Packit |
a7d494 |
return TRUE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_next (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return FALSE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* Moves @iter backward to the previous position where there is at least one
|
|
Packit |
a7d494 |
* mark. Returns %TRUE if @iter was moved.
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
gboolean
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_backward_iter (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
GtkTextIter *iter)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *mark;
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), FALSE);
|
|
Packit |
a7d494 |
g_return_val_if_fail (iter != NULL, FALSE);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == seq->priv->buffer, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
mark = gtk_text_buffer_create_mark (seq->priv->buffer,
|
|
Packit |
a7d494 |
NULL,
|
|
Packit |
a7d494 |
iter,
|
|
Packit |
a7d494 |
TRUE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_search (seq->priv->seq,
|
|
Packit |
a7d494 |
mark,
|
|
Packit |
a7d494 |
(GCompareDataFunc)compare_marks,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_delete_mark (seq->priv->buffer, mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_end (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_prev (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_end (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
/* The sequence is empty. */
|
|
Packit |
a7d494 |
return FALSE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (TRUE)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *cur_mark;
|
|
Packit |
a7d494 |
GtkTextIter cur_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur_mark = g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (gtk_text_iter_compare (&cur_iter, iter) < 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
*iter = cur_iter;
|
|
Packit |
a7d494 |
return TRUE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_begin (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_prev (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return FALSE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GSList *
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_get_marks_in_range (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
const GtkTextIter *iter1,
|
|
Packit |
a7d494 |
const GtkTextIter *iter2)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextIter start;
|
|
Packit |
a7d494 |
GtkTextIter end;
|
|
Packit |
a7d494 |
GtkTextMark *mark_start;
|
|
Packit |
a7d494 |
GSequenceIter *seq_iter;
|
|
Packit |
a7d494 |
GSequenceIter *first_seq_iter = NULL;
|
|
Packit |
a7d494 |
GSList *ret = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (iter1 != NULL, NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (iter2 != NULL, NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_iter_get_buffer (iter1) == seq->priv->buffer, NULL);
|
|
Packit |
a7d494 |
g_return_val_if_fail (gtk_text_iter_get_buffer (iter2) == seq->priv->buffer, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
start = *iter1;
|
|
Packit |
a7d494 |
end = *iter2;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_iter_order (&start, &end;;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
mark_start = gtk_text_buffer_create_mark (seq->priv->buffer,
|
|
Packit |
a7d494 |
NULL,
|
|
Packit |
a7d494 |
&start,
|
|
Packit |
a7d494 |
TRUE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_search (seq->priv->seq,
|
|
Packit |
a7d494 |
mark_start,
|
|
Packit |
a7d494 |
(GCompareDataFunc)compare_marks,
|
|
Packit |
a7d494 |
NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gtk_text_buffer_delete_mark (seq->priv->buffer, mark_start);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_end (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_prev (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_end (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
/* The sequence is empty. */
|
|
Packit |
a7d494 |
return NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* Find the first mark */
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (TRUE)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *cur_mark;
|
|
Packit |
a7d494 |
GtkTextIter cur_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur_mark = g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (gtk_text_iter_compare (&cur_iter, &start) < 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
first_seq_iter = seq_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_sequence_iter_is_begin (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_prev (seq_iter);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (first_seq_iter == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
/* The last mark in the sequence is before @start. */
|
|
Packit |
a7d494 |
return NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* Go forward until @end to fill the list of marks */
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
for (seq_iter = first_seq_iter;
|
|
Packit |
a7d494 |
!g_sequence_iter_is_end (seq_iter);
|
|
Packit |
a7d494 |
seq_iter = g_sequence_iter_next (seq_iter))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GtkTextMark *cur_mark;
|
|
Packit |
a7d494 |
GtkTextIter cur_iter;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur_mark = g_sequence_get (seq_iter);
|
|
Packit |
a7d494 |
gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (gtk_text_iter_compare (&end, &cur_iter) < 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
break;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ret = g_slist_prepend (ret, cur_mark);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return ret;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GSList *
|
|
Packit |
a7d494 |
_gtk_source_marks_sequence_get_marks_at_iter (GtkSourceMarksSequence *seq,
|
|
Packit |
a7d494 |
const GtkTextIter *iter)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
return _gtk_source_marks_sequence_get_marks_in_range (seq, iter, iter);
|
|
Packit |
a7d494 |
}
|