1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
2 /* gtksourcemark.c
3 * This file is part of GtkSourceView
4 *
5 * Copyright (C) 2007 - Johannes Schmid <jhs@gnome.org>
6 *
7 * GtkSourceView is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * GtkSourceView is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gtksourcemark.h"
27 #include "gtksourcebuffer.h"
28 #include "gtksourcebuffer-private.h"
29 #include "gtksourceview-i18n.h"
30
31 /**
32 * SECTION:mark
33 * @Short_description: Mark object for GtkSourceBuffer
34 * @Title: GtkSourceMark
35 * @See_also: #GtkSourceBuffer
36 *
37 * A #GtkSourceMark marks a position in the text where you want to display
38 * additional info. It is based on #GtkTextMark and thus is still valid after
39 * the text has changed though its position may change.
40 *
41 * #GtkSourceMark<!-- -->s are organised in categories which you have to set
42 * when you create the mark. Each category can have a priority, a pixbuf and
43 * other associated attributes. See gtk_source_view_set_mark_attributes().
44 * The pixbuf will be displayed in the margin at the line where the mark
45 * residents if the #GtkSourceView:show-line-marks property is set to %TRUE. If
46 * there are multiple marks in the same line, the pixbufs will be drawn on top
47 * of each other. The mark with the highest priority will be drawn on top.
48 */
49
50 enum
51 {
52 PROP_0,
53 PROP_CATEGORY
54 };
55
56 struct _GtkSourceMarkPrivate
57 {
58 gchar *category;
59 };
60
61 G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceMark, gtk_source_mark, GTK_TYPE_TEXT_MARK);
62
63 static void
gtk_source_mark_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)64 gtk_source_mark_set_property (GObject *object,
65 guint prop_id,
66 const GValue *value,
67 GParamSpec *pspec)
68 {
69 GtkSourceMarkPrivate *priv;
70
71 g_return_if_fail (GTK_SOURCE_IS_MARK (object));
72
73 priv = GTK_SOURCE_MARK (object)->priv;
74
75 switch (prop_id)
76 {
77 case PROP_CATEGORY:
78 g_return_if_fail (g_value_get_string (value) != NULL);
79 g_free (priv->category);
80 priv->category = g_value_dup_string (value);
81 break;
82 default:
83 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
84 prop_id,
85 pspec);
86 }
87 }
88
89 static void
gtk_source_mark_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)90 gtk_source_mark_get_property (GObject *object,
91 guint prop_id,
92 GValue *value,
93 GParamSpec *pspec)
94 {
95 GtkSourceMark *mark;
96
97 g_return_if_fail (GTK_SOURCE_IS_MARK (object));
98
99 mark = GTK_SOURCE_MARK (object);
100
101 switch (prop_id)
102 {
103 case PROP_CATEGORY:
104 g_value_set_string (value,
105 gtk_source_mark_get_category (mark));
106 break;
107 default:
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
109 prop_id,
110 pspec);
111 }
112 }
113
114 static void
gtk_source_mark_finalize(GObject * object)115 gtk_source_mark_finalize (GObject *object)
116 {
117 GtkSourceMark *mark = GTK_SOURCE_MARK (object);
118
119 g_free (mark->priv->category);
120
121 G_OBJECT_CLASS (gtk_source_mark_parent_class)->finalize (object);
122 }
123
124 static void
gtk_source_mark_class_init(GtkSourceMarkClass * klass)125 gtk_source_mark_class_init (GtkSourceMarkClass *klass)
126 {
127 GObjectClass *object_class;
128
129 object_class = G_OBJECT_CLASS (klass);
130
131 object_class->set_property = gtk_source_mark_set_property;
132 object_class->get_property = gtk_source_mark_get_property;
133 object_class->finalize = gtk_source_mark_finalize;
134
135 /**
136 * GtkSourceMark:category:
137 *
138 * The category of the #GtkSourceMark, classifies the mark and controls
139 * which pixbuf is used and with which priority it is drawn.
140 */
141 g_object_class_install_property (object_class,
142 PROP_CATEGORY,
143 g_param_spec_string ("category",
144 "Category",
145 "The mark category",
146 NULL,
147 G_PARAM_READWRITE |
148 G_PARAM_CONSTRUCT_ONLY |
149 G_PARAM_STATIC_STRINGS));
150 }
151
152 static void
gtk_source_mark_init(GtkSourceMark * mark)153 gtk_source_mark_init (GtkSourceMark *mark)
154 {
155 mark->priv = gtk_source_mark_get_instance_private (mark);
156 }
157
158 /**
159 * gtk_source_mark_new:
160 * @name: Name of the #GtkSourceMark, can be NULL when not using a name
161 * @category: is used to classify marks according to common characteristics
162 * (e.g. all the marks representing a bookmark could belong to the "bookmark"
163 * category, or all the marks representing a compilation error could belong to
164 * "error" category).
165 *
166 * Creates a text mark. Add it to a buffer using gtk_text_buffer_add_mark().
167 * If name is NULL, the mark is anonymous; otherwise, the mark can be retrieved
168 * by name using gtk_text_buffer_get_mark().
169 * Normally marks are created using the utility function
170 * gtk_source_buffer_create_source_mark().
171 *
172 * Returns: a new #GtkSourceMark that can be added using gtk_text_buffer_add_mark().
173 *
174 * Since: 2.2
175 */
176 GtkSourceMark *
gtk_source_mark_new(const gchar * name,const gchar * category)177 gtk_source_mark_new (const gchar *name,
178 const gchar *category)
179 {
180 g_return_val_if_fail (category != NULL, NULL);
181
182 return GTK_SOURCE_MARK (g_object_new (GTK_SOURCE_TYPE_MARK,
183 "category", category,
184 "name", name,
185 "left-gravity", TRUE,
186 NULL));
187 }
188
189 /**
190 * gtk_source_mark_get_category:
191 * @mark: a #GtkSourceMark.
192 *
193 * Returns the mark category.
194 *
195 * Returns: the category of the #GtkSourceMark.
196 *
197 * Since: 2.2
198 */
199 const gchar *
gtk_source_mark_get_category(GtkSourceMark * mark)200 gtk_source_mark_get_category (GtkSourceMark *mark)
201 {
202 g_return_val_if_fail (GTK_SOURCE_IS_MARK (mark), NULL);
203
204 return mark->priv->category;
205 }
206
207 /**
208 * gtk_source_mark_next:
209 * @mark: a #GtkSourceMark.
210 * @category: (nullable): a string specifying the mark category, or %NULL.
211 *
212 * Returns the next #GtkSourceMark in the buffer or %NULL if the mark
213 * was not added to a buffer. If there is no next mark, %NULL will be returned.
214 *
215 * If @category is %NULL, looks for marks of any category.
216 *
217 * Returns: (nullable) (transfer none): the next #GtkSourceMark, or %NULL.
218 *
219 * Since: 2.2
220 */
221 GtkSourceMark *
gtk_source_mark_next(GtkSourceMark * mark,const gchar * category)222 gtk_source_mark_next (GtkSourceMark *mark,
223 const gchar *category)
224 {
225 GtkTextBuffer *buffer;
226
227 g_return_val_if_fail (GTK_SOURCE_IS_MARK (mark), NULL);
228
229 buffer = gtk_text_mark_get_buffer (GTK_TEXT_MARK (mark));
230
231 if (buffer == NULL)
232 {
233 return NULL;
234 }
235
236 return _gtk_source_buffer_source_mark_next (GTK_SOURCE_BUFFER (buffer),
237 mark,
238 category);
239 }
240
241 /**
242 * gtk_source_mark_prev:
243 * @mark: a #GtkSourceMark.
244 * @category: a string specifying the mark category, or %NULL.
245 *
246 * Returns the previous #GtkSourceMark in the buffer or %NULL if the mark
247 * was not added to a buffer. If there is no previous mark, %NULL is returned.
248 *
249 * If @category is %NULL, looks for marks of any category
250 *
251 * Returns: (nullable) (transfer none): the previous #GtkSourceMark, or %NULL.
252 *
253 * Since: 2.2
254 */
255 GtkSourceMark *
gtk_source_mark_prev(GtkSourceMark * mark,const gchar * category)256 gtk_source_mark_prev (GtkSourceMark *mark,
257 const gchar *category)
258 {
259 GtkTextBuffer *buffer;
260
261 g_return_val_if_fail (GTK_SOURCE_IS_MARK (mark), NULL);
262
263 buffer = gtk_text_mark_get_buffer (GTK_TEXT_MARK (mark));
264
265 if (buffer == NULL)
266 {
267 return NULL;
268 }
269
270 return _gtk_source_buffer_source_mark_prev (GTK_SOURCE_BUFFER (buffer),
271 mark,
272 category);
273 }
274
275