File: | lapiz/lapiztextregion.c |
Warning: | line 331, column 4 Value stored to 'start_node' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- |
2 | * |
3 | * lapiztextregion.h - CtkTextMark based region utility functions |
4 | * |
5 | * This file is part of the CtkSourceView widget |
6 | * |
7 | * Copyright (C) 2002 Gustavo Giráldez <gustavo.giraldez@gmx.net> |
8 | * |
9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, |
22 | * Boston, MA 02110-1301, USA. |
23 | */ |
24 | |
25 | #ifdef HAVE_CONFIG_H1 |
26 | #include <config.h> |
27 | #endif |
28 | |
29 | #include <glib.h> |
30 | |
31 | #include "lapiztextregion.h" |
32 | |
33 | |
34 | #undef ENABLE_DEBUG |
35 | /* |
36 | #define ENABLE_DEBUG |
37 | */ |
38 | |
39 | #ifdef ENABLE_DEBUG |
40 | #define DEBUG(x) (x) |
41 | #else |
42 | #define DEBUG(x) |
43 | #endif |
44 | |
45 | typedef struct _Subregion { |
46 | CtkTextMark *start; |
47 | CtkTextMark *end; |
48 | } Subregion; |
49 | |
50 | struct _LapizTextRegion { |
51 | CtkTextBuffer *buffer; |
52 | GList *subregions; |
53 | guint32 time_stamp; |
54 | }; |
55 | |
56 | typedef struct _LapizTextRegionIteratorReal LapizTextRegionIteratorReal; |
57 | |
58 | struct _LapizTextRegionIteratorReal { |
59 | LapizTextRegion *region; |
60 | guint32 region_time_stamp; |
61 | |
62 | GList *subregions; |
63 | }; |
64 | |
65 | |
66 | /* ---------------------------------------------------------------------- |
67 | Private interface |
68 | ---------------------------------------------------------------------- */ |
69 | |
70 | /* Find and return a subregion node which contains the given text |
71 | iter. If left_side is TRUE, return the subregion which contains |
72 | the text iter or which is the leftmost; else return the rightmost |
73 | subregion */ |
74 | static GList * |
75 | find_nearest_subregion (LapizTextRegion *region, |
76 | const CtkTextIter *iter, |
77 | GList *begin, |
78 | gboolean leftmost, |
79 | gboolean include_edges) |
80 | { |
81 | GList *l, *retval; |
82 | |
83 | g_return_val_if_fail (region != NULL && iter != NULL, NULL)do { if ((region != ((void*)0) && iter != ((void*)0)) ) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char *) (__func__)), "region != NULL && iter != NULL"); return (((void*)0)); } } while (0); |
84 | |
85 | if (!begin) |
86 | begin = region->subregions; |
87 | |
88 | if (begin) |
89 | retval = begin->prev; |
90 | else |
91 | retval = NULL((void*)0); |
92 | |
93 | for (l = begin; l; l = l->next) { |
94 | CtkTextIter sr_iter; |
95 | Subregion *sr = l->data; |
96 | gint cmp; |
97 | |
98 | if (!leftmost) { |
99 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_iter, sr->end); |
100 | cmp = ctk_text_iter_compare (iter, &sr_iter); |
101 | if (cmp < 0 || (cmp == 0 && include_edges)) { |
102 | retval = l; |
103 | break; |
104 | } |
105 | |
106 | } else { |
107 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_iter, sr->start); |
108 | cmp = ctk_text_iter_compare (iter, &sr_iter); |
109 | if (cmp > 0 || (cmp == 0 && include_edges)) |
110 | retval = l; |
111 | else |
112 | break; |
113 | } |
114 | } |
115 | return retval; |
116 | } |
117 | |
118 | /* ---------------------------------------------------------------------- |
119 | Public interface |
120 | ---------------------------------------------------------------------- */ |
121 | |
122 | LapizTextRegion * |
123 | lapiz_text_region_new (CtkTextBuffer *buffer) |
124 | { |
125 | LapizTextRegion *region; |
126 | |
127 | g_return_val_if_fail (buffer != NULL, NULL)do { if ((buffer != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "buffer != NULL") ; return (((void*)0)); } } while (0); |
128 | |
129 | region = g_new (LapizTextRegion, 1)((LapizTextRegion *) g_malloc_n ((1), sizeof (LapizTextRegion ))); |
130 | region->buffer = buffer; |
131 | region->subregions = NULL((void*)0); |
132 | region->time_stamp = 0; |
133 | |
134 | return region; |
135 | } |
136 | |
137 | void |
138 | lapiz_text_region_destroy (LapizTextRegion *region, gboolean delete_marks) |
139 | { |
140 | g_return_if_fail (region != NULL)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return; } } while (0); |
141 | |
142 | while (region->subregions) { |
143 | Subregion *sr = region->subregions->data; |
144 | if (delete_marks) { |
145 | ctk_text_buffer_delete_mark (region->buffer, sr->start); |
146 | ctk_text_buffer_delete_mark (region->buffer, sr->end); |
147 | } |
148 | g_free (sr); |
149 | region->subregions = g_list_delete_link (region->subregions, |
150 | region->subregions); |
151 | } |
152 | region->buffer = NULL((void*)0); |
153 | region->time_stamp = 0; |
154 | |
155 | g_free (region); |
156 | } |
157 | |
158 | CtkTextBuffer * |
159 | lapiz_text_region_get_buffer (LapizTextRegion *region) |
160 | { |
161 | g_return_val_if_fail (region != NULL, NULL)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return (((void*)0)); } } while (0); |
162 | |
163 | return region->buffer; |
164 | } |
165 | |
166 | static void |
167 | lapiz_text_region_clear_zero_length_subregions (LapizTextRegion *region) |
168 | { |
169 | CtkTextIter start, end; |
170 | GList *node; |
171 | |
172 | g_return_if_fail (region != NULL)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return; } } while (0); |
173 | |
174 | for (node = region->subregions; node; ) { |
175 | Subregion *sr = node->data; |
176 | ctk_text_buffer_get_iter_at_mark (region->buffer, &start, sr->start); |
177 | ctk_text_buffer_get_iter_at_mark (region->buffer, &end, sr->end); |
178 | if (ctk_text_iter_equal (&start, &end)) { |
179 | ctk_text_buffer_delete_mark (region->buffer, sr->start); |
180 | ctk_text_buffer_delete_mark (region->buffer, sr->end); |
181 | g_free (sr); |
182 | if (node == region->subregions) |
183 | region->subregions = node = g_list_delete_link (node, node); |
184 | else |
185 | node = g_list_delete_link (node, node); |
186 | |
187 | ++region->time_stamp; |
188 | |
189 | } else { |
190 | node = node->next; |
191 | } |
192 | } |
193 | } |
194 | |
195 | void |
196 | lapiz_text_region_add (LapizTextRegion *region, |
197 | const CtkTextIter *_start, |
198 | const CtkTextIter *_end) |
199 | { |
200 | GList *start_node, *end_node; |
201 | CtkTextIter start, end; |
202 | |
203 | g_return_if_fail (region != NULL && _start != NULL && _end != NULL)do { if ((region != ((void*)0) && _start != ((void*)0 ) && _end != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL && _start != NULL && _end != NULL" ); return; } } while (0); |
204 | |
205 | start = *_start; |
206 | end = *_end; |
207 | |
208 | DEBUG (g_print ("---\n")); |
209 | DEBUG (lapiz_text_region_debug_print (region)); |
210 | DEBUG (g_message ("region_add (%d, %d)", |
211 | ctk_text_iter_get_offset (&start), |
212 | ctk_text_iter_get_offset (&end))); |
213 | |
214 | ctk_text_iter_order (&start, &end); |
215 | |
216 | /* don't add zero-length regions */ |
217 | if (ctk_text_iter_equal (&start, &end)) |
218 | return; |
219 | |
220 | /* find bounding subregions */ |
221 | start_node = find_nearest_subregion (region, &start, NULL((void*)0), FALSE(0), TRUE(!(0))); |
222 | end_node = find_nearest_subregion (region, &end, start_node, TRUE(!(0)), TRUE(!(0))); |
223 | |
224 | if (start_node == NULL((void*)0) || end_node == NULL((void*)0) || end_node == start_node->prev) { |
225 | /* create the new subregion */ |
226 | Subregion *sr = g_new0 (Subregion, 1)((Subregion *) g_malloc0_n ((1), sizeof (Subregion))); |
227 | sr->start = ctk_text_buffer_create_mark (region->buffer, NULL((void*)0), &start, TRUE(!(0))); |
228 | sr->end = ctk_text_buffer_create_mark (region->buffer, NULL((void*)0), &end, FALSE(0)); |
229 | |
230 | if (start_node == NULL((void*)0)) { |
231 | /* append the new region */ |
232 | region->subregions = g_list_append (region->subregions, sr); |
233 | |
234 | } else if (end_node == NULL((void*)0)) { |
235 | /* prepend the new region */ |
236 | region->subregions = g_list_prepend (region->subregions, sr); |
237 | |
238 | } else { |
239 | /* we are in the middle of two subregions */ |
240 | region->subregions = g_list_insert_before (region->subregions, |
241 | start_node, sr); |
242 | } |
243 | } |
244 | else { |
245 | CtkTextIter iter; |
246 | Subregion *sr = start_node->data; |
247 | if (start_node != end_node) { |
248 | /* we need to merge some subregions */ |
249 | GList *l = start_node->next; |
250 | Subregion *q; |
251 | |
252 | ctk_text_buffer_delete_mark (region->buffer, sr->end); |
253 | while (l != end_node) { |
254 | q = l->data; |
255 | ctk_text_buffer_delete_mark (region->buffer, q->start); |
256 | ctk_text_buffer_delete_mark (region->buffer, q->end); |
257 | g_free (q); |
258 | l = g_list_delete_link (l, l); |
259 | } |
260 | q = l->data; |
261 | ctk_text_buffer_delete_mark (region->buffer, q->start); |
262 | sr->end = q->end; |
263 | g_free (q); |
264 | l = g_list_delete_link (l, l); |
265 | } |
266 | /* now move marks if that action expands the region */ |
267 | ctk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->start); |
268 | if (ctk_text_iter_compare (&iter, &start) > 0) |
269 | ctk_text_buffer_move_mark (region->buffer, sr->start, &start); |
270 | ctk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->end); |
271 | if (ctk_text_iter_compare (&iter, &end) < 0) |
272 | ctk_text_buffer_move_mark (region->buffer, sr->end, &end); |
273 | } |
274 | |
275 | ++region->time_stamp; |
276 | |
277 | DEBUG (lapiz_text_region_debug_print (region)); |
278 | } |
279 | |
280 | void |
281 | lapiz_text_region_subtract (LapizTextRegion *region, |
282 | const CtkTextIter *_start, |
283 | const CtkTextIter *_end) |
284 | { |
285 | GList *start_node, *end_node, *node; |
286 | CtkTextIter sr_start_iter, sr_end_iter; |
287 | gboolean done; |
288 | gboolean start_is_outside, end_is_outside; |
289 | Subregion *sr; |
290 | CtkTextIter start, end; |
291 | |
292 | g_return_if_fail (region != NULL && _start != NULL && _end != NULL)do { if ((region != ((void*)0) && _start != ((void*)0 ) && _end != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL && _start != NULL && _end != NULL" ); return; } } while (0); |
293 | |
294 | start = *_start; |
295 | end = *_end; |
296 | |
297 | DEBUG (g_print ("---\n")); |
298 | DEBUG (lapiz_text_region_debug_print (region)); |
299 | DEBUG (g_message ("region_substract (%d, %d)", |
300 | ctk_text_iter_get_offset (&start), |
301 | ctk_text_iter_get_offset (&end))); |
302 | |
303 | ctk_text_iter_order (&start, &end); |
304 | |
305 | /* find bounding subregions */ |
306 | start_node = find_nearest_subregion (region, &start, NULL((void*)0), FALSE(0), FALSE(0)); |
307 | end_node = find_nearest_subregion (region, &end, start_node, TRUE(!(0)), FALSE(0)); |
308 | |
309 | /* easy case first */ |
310 | if (start_node == NULL((void*)0) || end_node == NULL((void*)0) || end_node == start_node->prev) |
311 | return; |
312 | |
313 | /* deal with the start point */ |
314 | start_is_outside = end_is_outside = FALSE(0); |
315 | |
316 | sr = start_node->data; |
317 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); |
318 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); |
319 | |
320 | if (ctk_text_iter_in_range (&start, &sr_start_iter, &sr_end_iter) && |
321 | !ctk_text_iter_equal (&start, &sr_start_iter)) { |
322 | /* the starting point is inside the first subregion */ |
323 | if (ctk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && |
324 | !ctk_text_iter_equal (&end, &sr_end_iter)) { |
325 | /* the ending point is also inside the first |
326 | subregion: we need to split */ |
327 | Subregion *new_sr = g_new0 (Subregion, 1)((Subregion *) g_malloc0_n ((1), sizeof (Subregion))); |
328 | new_sr->end = sr->end; |
329 | new_sr->start = ctk_text_buffer_create_mark (region->buffer, |
330 | NULL((void*)0), &end, TRUE(!(0))); |
331 | start_node = g_list_insert_before (start_node, start_node->next, new_sr); |
Value stored to 'start_node' is never read | |
332 | |
333 | sr->end = ctk_text_buffer_create_mark (region->buffer, |
334 | NULL((void*)0), &start, FALSE(0)); |
335 | |
336 | /* no further processing needed */ |
337 | DEBUG (g_message ("subregion splitted")); |
338 | |
339 | return; |
340 | } else { |
341 | /* the ending point is outside, so just move |
342 | the end of the subregion to the starting point */ |
343 | ctk_text_buffer_move_mark (region->buffer, sr->end, &start); |
344 | } |
345 | } else { |
346 | /* the starting point is outside (and so to the left) |
347 | of the first subregion */ |
348 | DEBUG (g_message ("start is outside")); |
349 | |
350 | start_is_outside = TRUE(!(0)); |
351 | } |
352 | |
353 | /* deal with the end point */ |
354 | if (start_node != end_node) { |
355 | sr = end_node->data; |
356 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); |
357 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); |
358 | } |
359 | |
360 | if (ctk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && |
361 | !ctk_text_iter_equal (&end, &sr_end_iter)) { |
362 | /* ending point is inside, move the start mark */ |
363 | ctk_text_buffer_move_mark (region->buffer, sr->start, &end); |
364 | } else { |
365 | end_is_outside = TRUE(!(0)); |
366 | DEBUG (g_message ("end is outside")); |
367 | |
368 | } |
369 | |
370 | /* finally remove any intermediate subregions */ |
371 | done = FALSE(0); |
372 | node = start_node; |
373 | |
374 | while (!done) { |
375 | if (node == end_node) |
376 | /* we are done, exit in the next iteration */ |
377 | done = TRUE(!(0)); |
378 | |
379 | if ((node == start_node && !start_is_outside) || |
380 | (node == end_node && !end_is_outside)) { |
381 | /* skip starting or ending node */ |
382 | node = node->next; |
383 | } else { |
384 | GList *l = node->next; |
385 | sr = node->data; |
386 | ctk_text_buffer_delete_mark (region->buffer, sr->start); |
387 | ctk_text_buffer_delete_mark (region->buffer, sr->end); |
388 | g_free (sr); |
389 | region->subregions = g_list_delete_link (region->subregions, |
390 | node); |
391 | node = l; |
392 | } |
393 | } |
394 | |
395 | ++region->time_stamp; |
396 | |
397 | DEBUG (lapiz_text_region_debug_print (region)); |
398 | |
399 | /* now get rid of empty subregions */ |
400 | lapiz_text_region_clear_zero_length_subregions (region); |
401 | |
402 | DEBUG (lapiz_text_region_debug_print (region)); |
403 | } |
404 | |
405 | gint |
406 | lapiz_text_region_subregions (LapizTextRegion *region) |
407 | { |
408 | g_return_val_if_fail (region != NULL, 0)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return (0); } } while (0); |
409 | |
410 | return g_list_length (region->subregions); |
411 | } |
412 | |
413 | gboolean |
414 | lapiz_text_region_nth_subregion (LapizTextRegion *region, |
415 | guint subregion, |
416 | CtkTextIter *start, |
417 | CtkTextIter *end) |
418 | { |
419 | Subregion *sr; |
420 | |
421 | g_return_val_if_fail (region != NULL, FALSE)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return ((0)); } } while (0); |
422 | |
423 | sr = g_list_nth_data (region->subregions, subregion); |
424 | if (sr == NULL((void*)0)) |
425 | return FALSE(0); |
426 | |
427 | if (start) |
428 | ctk_text_buffer_get_iter_at_mark (region->buffer, start, sr->start); |
429 | if (end) |
430 | ctk_text_buffer_get_iter_at_mark (region->buffer, end, sr->end); |
431 | |
432 | return TRUE(!(0)); |
433 | } |
434 | |
435 | LapizTextRegion * |
436 | lapiz_text_region_intersect (LapizTextRegion *region, |
437 | const CtkTextIter *_start, |
438 | const CtkTextIter *_end) |
439 | { |
440 | GList *start_node, *end_node, *node; |
441 | CtkTextIter sr_start_iter, sr_end_iter; |
442 | Subregion *sr, *new_sr; |
443 | gboolean done; |
444 | LapizTextRegion *new_region; |
445 | CtkTextIter start, end; |
446 | |
447 | g_return_val_if_fail (region != NULL && _start != NULL && _end != NULL, NULL)do { if ((region != ((void*)0) && _start != ((void*)0 ) && _end != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL && _start != NULL && _end != NULL" ); return (((void*)0)); } } while (0); |
448 | |
449 | start = *_start; |
450 | end = *_end; |
451 | |
452 | ctk_text_iter_order (&start, &end); |
453 | |
454 | /* find bounding subregions */ |
455 | start_node = find_nearest_subregion (region, &start, NULL((void*)0), FALSE(0), FALSE(0)); |
456 | end_node = find_nearest_subregion (region, &end, start_node, TRUE(!(0)), FALSE(0)); |
457 | |
458 | /* easy case first */ |
459 | if (start_node == NULL((void*)0) || end_node == NULL((void*)0) || end_node == start_node->prev) |
460 | return NULL((void*)0); |
461 | |
462 | new_region = lapiz_text_region_new (region->buffer); |
463 | done = FALSE(0); |
464 | |
465 | sr = start_node->data; |
466 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); |
467 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); |
468 | |
469 | /* starting node */ |
470 | if (ctk_text_iter_in_range (&start, &sr_start_iter, &sr_end_iter)) { |
471 | new_sr = g_new0 (Subregion, 1)((Subregion *) g_malloc0_n ((1), sizeof (Subregion))); |
472 | new_region->subregions = g_list_prepend (new_region->subregions, new_sr); |
473 | |
474 | new_sr->start = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
475 | &start, TRUE(!(0))); |
476 | if (start_node == end_node) { |
477 | /* things will finish shortly */ |
478 | done = TRUE(!(0)); |
479 | if (ctk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter)) |
480 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, |
481 | NULL((void*)0), &end, FALSE(0)); |
482 | else |
483 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, |
484 | NULL((void*)0), &sr_end_iter, |
485 | FALSE(0)); |
486 | } else { |
487 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
488 | &sr_end_iter, FALSE(0)); |
489 | } |
490 | node = start_node->next; |
491 | } else { |
492 | /* start should be the same as the subregion, so copy it in the loop */ |
493 | node = start_node; |
494 | } |
495 | |
496 | if (!done) { |
497 | while (node != end_node) { |
498 | /* copy intermediate subregions verbatim */ |
499 | sr = node->data; |
500 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, |
501 | sr->start); |
502 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); |
503 | |
504 | new_sr = g_new0 (Subregion, 1)((Subregion *) g_malloc0_n ((1), sizeof (Subregion))); |
505 | new_region->subregions = g_list_prepend (new_region->subregions, new_sr); |
506 | new_sr->start = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
507 | &sr_start_iter, TRUE(!(0))); |
508 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
509 | &sr_end_iter, FALSE(0)); |
510 | /* next node */ |
511 | node = node->next; |
512 | } |
513 | |
514 | /* ending node */ |
515 | sr = node->data; |
516 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); |
517 | ctk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); |
518 | |
519 | new_sr = g_new0 (Subregion, 1)((Subregion *) g_malloc0_n ((1), sizeof (Subregion))); |
520 | new_region->subregions = g_list_prepend (new_region->subregions, new_sr); |
521 | |
522 | new_sr->start = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
523 | &sr_start_iter, TRUE(!(0))); |
524 | |
525 | if (ctk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter)) |
526 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
527 | &end, FALSE(0)); |
528 | else |
529 | new_sr->end = ctk_text_buffer_create_mark (new_region->buffer, NULL((void*)0), |
530 | &sr_end_iter, FALSE(0)); |
531 | } |
532 | |
533 | new_region->subregions = g_list_reverse (new_region->subregions); |
534 | return new_region; |
535 | } |
536 | |
537 | static gboolean |
538 | check_iterator (LapizTextRegionIteratorReal *real) |
539 | { |
540 | if ((real->region == NULL((void*)0)) || |
541 | (real->region_time_stamp != real->region->time_stamp)) |
542 | { |
543 | g_warning("Invalid iterator: either the iterator " |
544 | "is uninitialized, or the region " |
545 | "has been modified since the iterator " |
546 | "was created."); |
547 | |
548 | return FALSE(0); |
549 | } |
550 | |
551 | return TRUE(!(0)); |
552 | } |
553 | |
554 | void |
555 | lapiz_text_region_get_iterator (LapizTextRegion *region, |
556 | LapizTextRegionIterator *iter, |
557 | guint start) |
558 | { |
559 | LapizTextRegionIteratorReal *real; |
560 | |
561 | g_return_if_fail (region != NULL)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return; } } while (0); |
562 | g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "iter != NULL"); return ; } } while (0); |
563 | |
564 | real = (LapizTextRegionIteratorReal *)iter; |
565 | |
566 | /* region->subregions may be NULL, -> end iter */ |
567 | |
568 | real->region = region; |
569 | real->subregions = g_list_nth (region->subregions, start); |
570 | real->region_time_stamp = region->time_stamp; |
571 | } |
572 | |
573 | gboolean |
574 | lapiz_text_region_iterator_is_end (LapizTextRegionIterator *iter) |
575 | { |
576 | LapizTextRegionIteratorReal *real; |
577 | |
578 | g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "iter != NULL"); return ((0)); } } while (0); |
579 | |
580 | real = (LapizTextRegionIteratorReal *)iter; |
581 | g_return_val_if_fail (check_iterator (real), FALSE)do { if ((check_iterator (real))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "check_iterator (real)" ); return ((0)); } } while (0); |
582 | |
583 | return (real->subregions == NULL((void*)0)); |
584 | } |
585 | |
586 | gboolean |
587 | lapiz_text_region_iterator_next (LapizTextRegionIterator *iter) |
588 | { |
589 | LapizTextRegionIteratorReal *real; |
590 | |
591 | g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "iter != NULL"); return ((0)); } } while (0); |
592 | |
593 | real = (LapizTextRegionIteratorReal *)iter; |
594 | g_return_val_if_fail (check_iterator (real), FALSE)do { if ((check_iterator (real))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "check_iterator (real)" ); return ((0)); } } while (0); |
595 | |
596 | if (real->subregions != NULL((void*)0)) { |
597 | real->subregions = g_list_next (real->subregions)((real->subregions) ? (((GList *)(real->subregions))-> next) : ((void*)0)); |
598 | return TRUE(!(0)); |
599 | } |
600 | else |
601 | return FALSE(0); |
602 | } |
603 | |
604 | void |
605 | lapiz_text_region_iterator_get_subregion (LapizTextRegionIterator *iter, |
606 | CtkTextIter *start, |
607 | CtkTextIter *end) |
608 | { |
609 | LapizTextRegionIteratorReal *real; |
610 | Subregion *sr; |
611 | |
612 | g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "iter != NULL"); return ; } } while (0); |
613 | |
614 | real = (LapizTextRegionIteratorReal *)iter; |
615 | g_return_if_fail (check_iterator (real))do { if ((check_iterator (real))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "check_iterator (real)" ); return; } } while (0); |
616 | g_return_if_fail (real->subregions != NULL)do { if ((real->subregions != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "real->subregions != NULL" ); return; } } while (0); |
617 | |
618 | sr = (Subregion*)real->subregions->data; |
619 | g_return_if_fail (sr != NULL)do { if ((sr != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "sr != NULL"); return ; } } while (0); |
620 | |
621 | if (start) |
622 | ctk_text_buffer_get_iter_at_mark (real->region->buffer, start, sr->start); |
623 | if (end) |
624 | ctk_text_buffer_get_iter_at_mark (real->region->buffer, end, sr->end); |
625 | } |
626 | |
627 | void |
628 | lapiz_text_region_debug_print (LapizTextRegion *region) |
629 | { |
630 | GList *l; |
631 | |
632 | g_return_if_fail (region != NULL)do { if ((region != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "region != NULL") ; return; } } while (0); |
633 | |
634 | g_print ("Subregions: "); |
635 | l = region->subregions; |
636 | while (l) { |
637 | Subregion *sr = l->data; |
638 | CtkTextIter iter1, iter2; |
639 | ctk_text_buffer_get_iter_at_mark (region->buffer, &iter1, sr->start); |
640 | ctk_text_buffer_get_iter_at_mark (region->buffer, &iter2, sr->end); |
641 | g_print ("%d-%d ", ctk_text_iter_get_offset (&iter1), |
642 | ctk_text_iter_get_offset (&iter2)); |
643 | l = l->next; |
644 | } |
645 | g_print ("\n"); |
646 | } |