1 /***************************************************************************
2 * sourceview-cell.c
3 *
4 * So Mai 21 14:44:13 2006
5 * Copyright 2006 Johannes Schmid
6 * jhs@cvs.gnome.org
7 ***************************************************************************/
8
9 /*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 #include "sourceview-cell.h"
26
27 #include <libanjuta/interfaces/ianjuta-editor-cell.h>
28 #include <libanjuta/interfaces/ianjuta-editor-cell-style.h>
29 #include <libanjuta/interfaces/ianjuta-iterable.h>
30 #include <libanjuta/anjuta-utils.h>
31 #include <libanjuta/anjuta-debug.h>
32
33 #include <gtk/gtk.h>
34 #include <string.h>
35 #include <gtksourceview/gtksource.h>
36
37 static void sourceview_cell_class_init(SourceviewCellClass *klass);
38 static void sourceview_cell_instance_init(SourceviewCell *sp);
39 static void sourceview_cell_finalize(GObject *object);
40
41 struct _SourceviewCellPrivate {
42 GtkTextView* view;
43 GtkTextBuffer* buffer;
44
45 gint offset;
46 };
47
48 static gpointer sourceview_cell_parent_class = NULL;
49
50 /**
51 * sourceview_cell_update_offset:
52 * @cell: self
53 *
54 * Update the internal offset
55 */
56 static void
sourceview_cell_update_offset(SourceviewCell * cell,GtkTextIter * iter)57 sourceview_cell_update_offset (SourceviewCell* cell, GtkTextIter* iter)
58 {
59 cell->priv->offset = gtk_text_iter_get_offset (iter);
60 }
61
62 /**
63 * sourceview_cell_get_iter:
64 * @cell: self
65 * @iter: iterator to set
66 * Get the iterator for cell
67 */
68 void
sourceview_cell_get_iter(SourceviewCell * cell,GtkTextIter * iter)69 sourceview_cell_get_iter (SourceviewCell* cell, GtkTextIter* iter)
70 {
71 gtk_text_buffer_get_iter_at_offset (cell->priv->buffer,
72 iter,
73 cell->priv->offset);
74 }
75
76 static void
sourceview_cell_class_init(SourceviewCellClass * klass)77 sourceview_cell_class_init(SourceviewCellClass *klass)
78 {
79 GObjectClass *object_class = G_OBJECT_CLASS(klass);
80 sourceview_cell_parent_class = g_type_class_peek_parent(klass);
81
82
83 object_class->finalize = sourceview_cell_finalize;
84 }
85
86 static void
sourceview_cell_instance_init(SourceviewCell * obj)87 sourceview_cell_instance_init(SourceviewCell *obj)
88 {
89 obj->priv = g_slice_new0(SourceviewCellPrivate);
90
91 /* Initialize private members, etc. */
92 }
93
94 static void
sourceview_cell_finalize(GObject * object)95 sourceview_cell_finalize(GObject *object)
96 {
97 SourceviewCell *cobj;
98 cobj = SOURCEVIEW_CELL(object);
99
100 g_slice_free(SourceviewCellPrivate, cobj->priv);
101 G_OBJECT_CLASS(sourceview_cell_parent_class)->finalize(object);
102 }
103
104 SourceviewCell *
sourceview_cell_new(GtkTextIter * iter,GtkTextView * view)105 sourceview_cell_new(GtkTextIter* iter, GtkTextView* view)
106 {
107 SourceviewCell *obj;
108
109 obj = SOURCEVIEW_CELL(g_object_new(SOURCEVIEW_TYPE_CELL, NULL));
110
111 obj->priv->buffer = gtk_text_view_get_buffer(view);
112 obj->priv->view = view;
113 obj->priv->offset = gtk_text_iter_get_offset (iter);
114
115 return obj;
116 }
117
118 static gchar*
icell_get_character(IAnjutaEditorCell * icell,GError ** e)119 icell_get_character(IAnjutaEditorCell* icell, GError** e)
120 {
121 SourceviewCell* cell = SOURCEVIEW_CELL(icell);
122 GtkTextIter iter;
123 sourceview_cell_get_iter (cell, &iter);
124 gunichar c = gtk_text_iter_get_char (&iter);
125 gchar* outbuf = g_new0(gchar, 6);
126 g_unichar_to_utf8 (c, outbuf);
127 return outbuf;
128 }
129
130 static gint
icell_get_length(IAnjutaEditorCell * icell,GError ** e)131 icell_get_length(IAnjutaEditorCell* icell, GError** e)
132 {
133 gchar* text = icell_get_character(icell, e);
134 gint retval = 0;
135 if (text)
136 retval = g_utf8_strlen (text, -1);
137 g_free(text);
138 return retval;
139 }
140
141 static gchar
icell_get_char(IAnjutaEditorCell * icell,gint index,GError ** e)142 icell_get_char(IAnjutaEditorCell* icell, gint index, GError** e)
143 {
144 SourceviewCell* cell = SOURCEVIEW_CELL(icell);
145 GtkTextIter iter;
146 sourceview_cell_get_iter (cell, &iter);
147 gunichar c = gtk_text_iter_get_char (&iter);
148 gchar* outbuf = g_new0(gchar, 6);
149 gint len = g_unichar_to_utf8 (c, outbuf);
150 gchar retval;
151 if (index < len)
152 retval = outbuf[index];
153 else
154 retval = 0;
155 g_free (outbuf);
156 return retval;
157 }
158
159 static IAnjutaEditorAttribute
icell_get_attribute(IAnjutaEditorCell * icell,GError ** e)160 icell_get_attribute (IAnjutaEditorCell* icell, GError **e)
161 {
162 IAnjutaEditorAttribute attrib = IANJUTA_EDITOR_TEXT;
163 GtkTextIter iter;
164 SourceviewCell* cell = SOURCEVIEW_CELL(icell);
165
166 sourceview_cell_get_iter (cell, &iter);
167
168 if (gtk_source_buffer_iter_has_context_class (GTK_SOURCE_BUFFER(cell->priv->buffer), &iter, "string"))
169 attrib = IANJUTA_EDITOR_STRING;
170 else if (gtk_source_buffer_iter_has_context_class (GTK_SOURCE_BUFFER(cell->priv->buffer), &iter, "comment"))
171 attrib = IANJUTA_EDITOR_COMMENT;
172 else if (gtk_source_buffer_iter_has_context_class (GTK_SOURCE_BUFFER(cell->priv->buffer), &iter, "keyword"))
173 attrib = IANJUTA_EDITOR_KEYWORD;
174
175 return attrib;
176 }
177
178 static void
icell_iface_init(IAnjutaEditorCellIface * iface)179 icell_iface_init(IAnjutaEditorCellIface* iface)
180 {
181 iface->get_character = icell_get_character;
182 iface->get_char = icell_get_char;
183 iface->get_length = icell_get_length;
184 iface->get_attribute = icell_get_attribute;
185 }
186
187 static gboolean
iiter_first(IAnjutaIterable * iiter,GError ** e)188 iiter_first(IAnjutaIterable* iiter, GError** e)
189 {
190 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
191 cell->priv->offset = 0;
192 return TRUE;
193 }
194
195 static gboolean
iiter_next(IAnjutaIterable * iiter,GError ** e)196 iiter_next(IAnjutaIterable* iiter, GError** e)
197 {
198 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
199 GtkTextIter iter;
200 gboolean retval;
201 sourceview_cell_get_iter (cell, &iter);
202 retval = gtk_text_iter_forward_char (&iter);
203 sourceview_cell_update_offset (cell, &iter);
204
205 return retval;
206 }
207
208 static gboolean
iiter_previous(IAnjutaIterable * iiter,GError ** e)209 iiter_previous(IAnjutaIterable* iiter, GError** e)
210 {
211 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
212 if (cell->priv->offset > 0)
213 {
214 cell->priv->offset--;
215 return TRUE;
216 }
217
218 return FALSE;
219 }
220
221 static gboolean
iiter_last(IAnjutaIterable * iiter,GError ** e)222 iiter_last(IAnjutaIterable* iiter, GError** e)
223 {
224 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
225 cell->priv->offset = -1;
226 return TRUE;
227 }
228
229 static void
iiter_foreach(IAnjutaIterable * iiter,GFunc callback,gpointer data,GError ** e)230 iiter_foreach(IAnjutaIterable* iiter, GFunc callback, gpointer data, GError** e)
231 {
232 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
233 gint old_offset = cell->priv->offset;
234
235 iiter_first (IANJUTA_ITERABLE(cell), NULL);
236
237 while (iiter_next(IANJUTA_ITERABLE(cell), NULL))
238 {
239 (*callback)(cell, data);
240 }
241 cell->priv->offset = old_offset;
242 }
243
244 static gboolean
iiter_set_position(IAnjutaIterable * iiter,gint position,GError ** e)245 iiter_set_position (IAnjutaIterable* iiter, gint position, GError** e)
246 {
247 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
248 cell->priv->offset = position;
249 return TRUE;
250 }
251
252 static gint
iiter_get_position(IAnjutaIterable * iiter,GError ** e)253 iiter_get_position(IAnjutaIterable* iiter, GError** e)
254 {
255 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
256 return cell->priv->offset;
257 }
258
259 static gint
iiter_get_length(IAnjutaIterable * iiter,GError ** e)260 iiter_get_length(IAnjutaIterable* iiter, GError** e)
261 {
262 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
263
264 return gtk_text_buffer_get_char_count (cell->priv->buffer);
265 }
266
267 static IAnjutaIterable *
iiter_clone(IAnjutaIterable * iiter,GError ** e)268 iiter_clone (IAnjutaIterable *iiter, GError **e)
269 {
270 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
271 GtkTextIter iter;
272 sourceview_cell_get_iter (cell, &iter);
273 return IANJUTA_ITERABLE (sourceview_cell_new (&iter, cell->priv->view));
274 }
275
276 static void
iiter_assign(IAnjutaIterable * iiter,IAnjutaIterable * src_iter,GError ** e)277 iiter_assign (IAnjutaIterable *iiter, IAnjutaIterable *src_iter, GError **e)
278 {
279 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
280 SourceviewCell* src_cell = SOURCEVIEW_CELL(src_iter);
281 cell->priv->offset = src_cell->priv->offset;
282 }
283
284 static gint
iiter_compare(IAnjutaIterable * iiter,IAnjutaIterable * iother_iter,GError ** e)285 iiter_compare (IAnjutaIterable *iiter, IAnjutaIterable *iother_iter, GError **e)
286 {
287 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
288 SourceviewCell* other_cell = SOURCEVIEW_CELL(iother_iter);
289
290 GtkTextIter iter;
291 GtkTextIter other_iter;
292
293 sourceview_cell_get_iter (cell, &iter);
294 sourceview_cell_get_iter (other_cell, &other_iter);
295
296 return gtk_text_iter_compare (&iter, &other_iter);
297 }
298
299 static gint
iiter_diff(IAnjutaIterable * iiter,IAnjutaIterable * iother_iter,GError ** e)300 iiter_diff (IAnjutaIterable *iiter, IAnjutaIterable *iother_iter, GError **e)
301 {
302 SourceviewCell* cell = SOURCEVIEW_CELL(iiter);
303 SourceviewCell* other_cell = SOURCEVIEW_CELL(iother_iter);
304
305 return (other_cell->priv->offset - cell->priv->offset);
306 }
307
308 static void
iiter_iface_init(IAnjutaIterableIface * iface)309 iiter_iface_init(IAnjutaIterableIface* iface)
310 {
311 iface->first = iiter_first;
312 iface->next = iiter_next;
313 iface->previous = iiter_previous;
314 iface->last = iiter_last;
315 iface->foreach = iiter_foreach;
316 iface->set_position = iiter_set_position;
317 iface->get_position = iiter_get_position;
318 iface->get_length = iiter_get_length;
319 iface->assign = iiter_assign;
320 iface->clone = iiter_clone;
321 iface->diff = iiter_diff;
322 iface->compare = iiter_compare;
323 }
324
325
326 ANJUTA_TYPE_BEGIN(SourceviewCell, sourceview_cell, G_TYPE_OBJECT);
327 ANJUTA_TYPE_ADD_INTERFACE(icell, IANJUTA_TYPE_EDITOR_CELL);
328 ANJUTA_TYPE_ADD_INTERFACE(iiter, IANJUTA_TYPE_ITERABLE);
329 ANJUTA_TYPE_END;
330