1 /* hypertextview.c generated by valac 0.48.6, the Vala compiler
2 * generated from hypertextview.vala, do not modify */
3
4 /*
5 * Notes - panel plugin for Xfce Desktop Environment
6 * Copyright (c) 2009-2010 Mike Massonnet <mmassonnet@xfce.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include <gtk/gtk.h>
24 #include <glib-object.h>
25 #include <gdk/gdk.h>
26 #include <glib.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <pango/pango.h>
30 #include <gio/gio.h>
31
32 #define XNP_TYPE_HYPERTEXT_VIEW (xnp_hypertext_view_get_type ())
33 #define XNP_HYPERTEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView))
34 #define XNP_HYPERTEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextViewClass))
35 #define XNP_IS_HYPERTEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XNP_TYPE_HYPERTEXT_VIEW))
36 #define XNP_IS_HYPERTEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XNP_TYPE_HYPERTEXT_VIEW))
37 #define XNP_HYPERTEXT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextViewClass))
38
39 typedef struct _XnpHypertextView XnpHypertextView;
40 typedef struct _XnpHypertextViewClass XnpHypertextViewClass;
41 typedef struct _XnpHypertextViewPrivate XnpHypertextViewPrivate;
42 enum {
43 XNP_HYPERTEXT_VIEW_0_PROPERTY,
44 XNP_HYPERTEXT_VIEW_FONT_PROPERTY,
45 XNP_HYPERTEXT_VIEW_NUM_PROPERTIES
46 };
47 static GParamSpec* xnp_hypertext_view_properties[XNP_HYPERTEXT_VIEW_NUM_PROPERTIES];
48 #define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
49 #define _g_free0(var) (var = (g_free (var), NULL))
50 #define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
51 #define __vala_PangoFontDescription_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoFontDescription_free (var), NULL)))
52 #define __vala_PangoTabArray_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoTabArray_free (var), NULL)))
53
54 struct _XnpHypertextView {
55 GtkTextView parent_instance;
56 XnpHypertextViewPrivate * priv;
57 };
58
59 struct _XnpHypertextViewClass {
60 GtkTextViewClass parent_class;
61 };
62
63 struct _XnpHypertextViewPrivate {
64 GdkCursor* hand_cursor;
65 GdkCursor* regular_cursor;
66 gboolean cursor_over_link;
67 guint undo_timeout;
68 gint undo_cursor_pos;
69 gchar* undo_text;
70 gchar* redo_text;
71 guint tag_timeout;
72 GtkTextTag* tag_link;
73 gchar* _font;
74 };
75
76 static gint XnpHypertextView_private_offset;
77 static gpointer xnp_hypertext_view_parent_class = NULL;
78
79 GType xnp_hypertext_view_get_type (void) G_GNUC_CONST;
80 G_DEFINE_AUTOPTR_CLEANUP_FUNC (XnpHypertextView, g_object_unref)
81 XnpHypertextView* xnp_hypertext_view_new (void);
82 XnpHypertextView* xnp_hypertext_view_construct (GType object_type);
83 static gboolean xnp_hypertext_view_button_release_event_cb (XnpHypertextView* self,
84 GtkWidget* hypertextview,
85 GdkEventButton* event);
86 static gboolean _xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event (GtkWidget* _sender,
87 GdkEventButton* event,
88 gpointer self);
89 static gboolean xnp_hypertext_view_motion_notify_event_cb (XnpHypertextView* self,
90 GtkWidget* hypertextview,
91 GdkEventMotion* event);
92 static gboolean _xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event (GtkWidget* _sender,
93 GdkEventMotion* event,
94 gpointer self);
95 static void xnp_hypertext_view_move_cursor_cb (XnpHypertextView* self,
96 GtkWidget* hypertextview,
97 GtkMovementStep step,
98 gint count,
99 gboolean extend_selection);
100 static void _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor (GtkTextView* _sender,
101 GtkMovementStep step,
102 gint count,
103 gboolean extend_selection,
104 gpointer self);
105 static void xnp_hypertext_view_buffer_changed_cb (XnpHypertextView* self);
106 static void _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed (GtkTextBuffer* _sender,
107 gpointer self);
108 static void xnp_hypertext_view_insert_text_cb (XnpHypertextView* self,
109 GtkTextBuffer* buffer,
110 GtkTextIter* location,
111 const gchar* text,
112 gint len);
113 static void _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text (GtkTextBuffer* _sender,
114 GtkTextIter* pos,
115 const gchar* new_text,
116 gint new_text_length,
117 gpointer self);
118 static void xnp_hypertext_view_delete_range_cb (XnpHypertextView* self,
119 GtkTextBuffer* buffer,
120 GtkTextIter* start,
121 GtkTextIter* end);
122 static void _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range (GtkTextBuffer* _sender,
123 GtkTextIter* start,
124 GtkTextIter* end,
125 gpointer self);
126 static gboolean xnp_hypertext_view_undo_snapshot (XnpHypertextView* self);
127 void xnp_hypertext_view_update_tags (XnpHypertextView* self);
128 static gboolean _xnp_hypertext_view_undo_snapshot_gsource_func (gpointer self);
129 static gboolean xnp_hypertext_view_tag_timeout_cb (XnpHypertextView* self);
130 static gboolean _xnp_hypertext_view_tag_timeout_cb_gsource_func (gpointer self);
131 static void xnp_hypertext_view_tag_timeout_init (XnpHypertextView* self);
132 void xnp_hypertext_view_undo (XnpHypertextView* self);
133 const gchar* xnp_hypertext_view_get_font (XnpHypertextView* self);
134 void xnp_hypertext_view_set_font (XnpHypertextView* self,
135 const gchar* value);
136 static void _vala_PangoFontDescription_free (PangoFontDescription* self);
137 static GObject * xnp_hypertext_view_constructor (GType type,
138 guint n_construct_properties,
139 GObjectConstructParam * construct_properties);
140 static void _vala_PangoTabArray_free (PangoTabArray* self);
141 static void xnp_hypertext_view_finalize (GObject * obj);
142 static GType xnp_hypertext_view_get_type_once (void);
143 static void _vala_xnp_hypertext_view_get_property (GObject * object,
144 guint property_id,
145 GValue * value,
146 GParamSpec * pspec);
147 static void _vala_xnp_hypertext_view_set_property (GObject * object,
148 guint property_id,
149 const GValue * value,
150 GParamSpec * pspec);
151
152 static inline gpointer
xnp_hypertext_view_get_instance_private(XnpHypertextView * self)153 xnp_hypertext_view_get_instance_private (XnpHypertextView* self)
154 {
155 return G_STRUCT_MEMBER_P (self, XnpHypertextView_private_offset);
156 }
157
158 static gboolean
_xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event(GtkWidget * _sender,GdkEventButton * event,gpointer self)159 _xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event (GtkWidget* _sender,
160 GdkEventButton* event,
161 gpointer self)
162 {
163 gboolean result;
164 result = xnp_hypertext_view_button_release_event_cb ((XnpHypertextView*) self, _sender, event);
165 return result;
166 }
167
168 static gboolean
_xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event(GtkWidget * _sender,GdkEventMotion * event,gpointer self)169 _xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event (GtkWidget* _sender,
170 GdkEventMotion* event,
171 gpointer self)
172 {
173 gboolean result;
174 result = xnp_hypertext_view_motion_notify_event_cb ((XnpHypertextView*) self, _sender, event);
175 return result;
176 }
177
178 static void
_xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor(GtkTextView * _sender,GtkMovementStep step,gint count,gboolean extend_selection,gpointer self)179 _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor (GtkTextView* _sender,
180 GtkMovementStep step,
181 gint count,
182 gboolean extend_selection,
183 gpointer self)
184 {
185 xnp_hypertext_view_move_cursor_cb ((XnpHypertextView*) self, _sender, step, count, extend_selection);
186 }
187
188 static void
_xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed(GtkTextBuffer * _sender,gpointer self)189 _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed (GtkTextBuffer* _sender,
190 gpointer self)
191 {
192 xnp_hypertext_view_buffer_changed_cb ((XnpHypertextView*) self);
193 }
194
195 static void
_xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text(GtkTextBuffer * _sender,GtkTextIter * pos,const gchar * new_text,gint new_text_length,gpointer self)196 _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text (GtkTextBuffer* _sender,
197 GtkTextIter* pos,
198 const gchar* new_text,
199 gint new_text_length,
200 gpointer self)
201 {
202 xnp_hypertext_view_insert_text_cb ((XnpHypertextView*) self, _sender, pos, new_text, new_text_length);
203 }
204
205 static void
_xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range(GtkTextBuffer * _sender,GtkTextIter * start,GtkTextIter * end,gpointer self)206 _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range (GtkTextBuffer* _sender,
207 GtkTextIter* start,
208 GtkTextIter* end,
209 gpointer self)
210 {
211 xnp_hypertext_view_delete_range_cb ((XnpHypertextView*) self, _sender, start, end);
212 }
213
214 static gpointer
_g_object_ref0(gpointer self)215 _g_object_ref0 (gpointer self)
216 {
217 return self ? g_object_ref (self) : NULL;
218 }
219
220 XnpHypertextView*
xnp_hypertext_view_construct(GType object_type)221 xnp_hypertext_view_construct (GType object_type)
222 {
223 XnpHypertextView * self = NULL;
224 GtkTextIter iter = {0};
225 GtkTextBuffer* _tmp0_;
226 GtkTextBuffer* _tmp1_;
227 GtkTextBuffer* _tmp2_;
228 GtkTextBuffer* _tmp3_;
229 GtkTextBuffer* _tmp4_;
230 GtkTextBuffer* _tmp5_;
231 GtkTextBuffer* _tmp6_;
232 GtkTextBuffer* _tmp7_;
233 GtkTextIter _tmp8_ = {0};
234 GtkTextBuffer* _tmp9_;
235 GtkTextBuffer* _tmp10_;
236 GtkTextIter _tmp11_;
237 GtkTextBuffer* _tmp12_;
238 GtkTextBuffer* _tmp13_;
239 GtkTextTag* _tmp14_;
240 GtkTextTag* _tmp15_;
241 self = (XnpHypertextView*) g_object_new (object_type, NULL);
242 g_signal_connect_object ((GtkWidget*) self, "button-release-event", (GCallback) _xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event, self, 0);
243 g_signal_connect_object ((GtkWidget*) self, "motion-notify-event", (GCallback) _xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event, self, 0);
244 g_signal_connect_object ((GtkTextView*) self, "move-cursor", (GCallback) _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor, self, 0);
245 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
246 _tmp1_ = _tmp0_;
247 g_signal_connect_object (_tmp1_, "changed", (GCallback) _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed, self, 0);
248 _tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
249 _tmp3_ = _tmp2_;
250 g_signal_connect_object (_tmp3_, "insert-text", (GCallback) _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text, self, 0);
251 _tmp4_ = gtk_text_view_get_buffer ((GtkTextView*) self);
252 _tmp5_ = _tmp4_;
253 g_signal_connect_object (_tmp5_, "delete-range", (GCallback) _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range, self, 0);
254 _tmp6_ = gtk_text_view_get_buffer ((GtkTextView*) self);
255 _tmp7_ = _tmp6_;
256 gtk_text_buffer_get_iter_at_offset (_tmp7_, &_tmp8_, 0);
257 iter = _tmp8_;
258 _tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) self);
259 _tmp10_ = _tmp9_;
260 _tmp11_ = iter;
261 gtk_text_buffer_create_mark (_tmp10_, "undo-pos", &_tmp11_, FALSE);
262 _tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
263 _tmp13_ = _tmp12_;
264 _tmp14_ = gtk_text_buffer_create_tag (_tmp13_, "link", "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL, NULL);
265 _tmp15_ = _g_object_ref0 (_tmp14_);
266 _g_object_unref0 (self->priv->tag_link);
267 self->priv->tag_link = _tmp15_;
268 return self;
269 }
270
271 XnpHypertextView*
xnp_hypertext_view_new(void)272 xnp_hypertext_view_new (void)
273 {
274 return xnp_hypertext_view_construct (XNP_TYPE_HYPERTEXT_VIEW);
275 }
276
277 /**
278 * button_release_event_cb:
279 *
280 * Event to open links.
281 */
282 static gboolean
xnp_hypertext_view_button_release_event_cb(XnpHypertextView * self,GtkWidget * hypertextview,GdkEventButton * event)283 xnp_hypertext_view_button_release_event_cb (XnpHypertextView* self,
284 GtkWidget* hypertextview,
285 GdkEventButton* event)
286 {
287 GtkTextIter start = {0};
288 GtkTextIter end = {0};
289 GtkTextIter iter = {0};
290 gchar* link = NULL;
291 gint x = 0;
292 gint y = 0;
293 GtkTextBuffer* _tmp0_;
294 GtkTextBuffer* _tmp1_;
295 GtkTextIter _tmp2_ = {0};
296 GtkTextIter _tmp3_ = {0};
297 gint _tmp4_ = 0;
298 gint _tmp5_ = 0;
299 GtkTextIter _tmp6_ = {0};
300 GtkTextTag* _tmp7_;
301 GError* _inner_error0_ = NULL;
302 gboolean result = FALSE;
303 g_return_val_if_fail (self != NULL, FALSE);
304 g_return_val_if_fail (hypertextview != NULL, FALSE);
305 g_return_val_if_fail (event != NULL, FALSE);
306 if (event->button != ((guint) 1)) {
307 result = FALSE;
308 _g_free0 (link);
309 return result;
310 }
311 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
312 _tmp1_ = _tmp0_;
313 gtk_text_buffer_get_selection_bounds (_tmp1_, &_tmp2_, &_tmp3_);
314 start = _tmp2_;
315 end = _tmp3_;
316 if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) {
317 result = FALSE;
318 _g_free0 (link);
319 return result;
320 }
321 gtk_text_view_window_to_buffer_coords ((GtkTextView*) self, GTK_TEXT_WINDOW_WIDGET, (gint) event->x, (gint) event->y, &_tmp4_, &_tmp5_);
322 x = _tmp4_;
323 y = _tmp5_;
324 gtk_text_view_get_iter_at_location ((GtkTextView*) self, &_tmp6_, x, y);
325 iter = _tmp6_;
326 _tmp7_ = self->priv->tag_link;
327 if (gtk_text_iter_has_tag (&iter, _tmp7_)) {
328 GtkTextIter _tmp8_;
329 GtkTextIter _tmp9_;
330 GtkTextTag* _tmp10_;
331 GtkTextTag* _tmp12_;
332 GtkTextIter _tmp13_;
333 gchar* _tmp14_;
334 _tmp8_ = iter;
335 end = _tmp8_;
336 _tmp9_ = end;
337 start = _tmp9_;
338 _tmp10_ = self->priv->tag_link;
339 if (!gtk_text_iter_starts_tag (&start, _tmp10_)) {
340 GtkTextTag* _tmp11_;
341 _tmp11_ = self->priv->tag_link;
342 gtk_text_iter_backward_to_tag_toggle (&start, _tmp11_);
343 }
344 _tmp12_ = self->priv->tag_link;
345 gtk_text_iter_forward_to_tag_toggle (&end, _tmp12_);
346 _tmp13_ = end;
347 _tmp14_ = gtk_text_iter_get_text (&start, &_tmp13_);
348 _g_free0 (link);
349 link = _tmp14_;
350 {
351 const gchar* _tmp15_;
352 gchar* _tmp16_;
353 gchar* _tmp17_;
354 _tmp15_ = link;
355 _tmp16_ = g_strconcat ("exo-open ", _tmp15_, NULL);
356 _tmp17_ = _tmp16_;
357 g_spawn_command_line_async (_tmp17_, &_inner_error0_);
358 _g_free0 (_tmp17_);
359 if (G_UNLIKELY (_inner_error0_ != NULL)) {
360 goto __catch0_g_error;
361 }
362 result = FALSE;
363 _g_free0 (link);
364 return result;
365 }
366 goto __finally0;
367 __catch0_g_error:
368 {
369 g_clear_error (&_inner_error0_);
370 }
371 __finally0:
372 if (G_UNLIKELY (_inner_error0_ != NULL)) {
373 gboolean _tmp18_ = FALSE;
374 _g_free0 (link);
375 g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
376 g_clear_error (&_inner_error0_);
377 return _tmp18_;
378 }
379 {
380 const gchar* _tmp19_;
381 _tmp19_ = link;
382 g_app_info_launch_default_for_uri (_tmp19_, NULL, &_inner_error0_);
383 if (G_UNLIKELY (_inner_error0_ != NULL)) {
384 goto __catch1_g_error;
385 }
386 result = FALSE;
387 _g_free0 (link);
388 return result;
389 }
390 goto __finally1;
391 __catch1_g_error:
392 {
393 GError* e = NULL;
394 GError* _tmp20_;
395 const gchar* _tmp21_;
396 e = _inner_error0_;
397 _inner_error0_ = NULL;
398 _tmp20_ = e;
399 _tmp21_ = _tmp20_->message;
400 g_message ("hypertextview.vala:127: Unable to open link with default handler: %s", _tmp21_);
401 _g_error_free0 (e);
402 }
403 __finally1:
404 if (G_UNLIKELY (_inner_error0_ != NULL)) {
405 gboolean _tmp22_ = FALSE;
406 _g_free0 (link);
407 g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
408 g_clear_error (&_inner_error0_);
409 return _tmp22_;
410 }
411 {
412 const gchar* _tmp23_;
413 gchar* _tmp24_;
414 gchar* _tmp25_;
415 _tmp23_ = link;
416 _tmp24_ = g_strconcat ("xdg-open ", _tmp23_, NULL);
417 _tmp25_ = _tmp24_;
418 g_spawn_command_line_async (_tmp25_, &_inner_error0_);
419 _g_free0 (_tmp25_);
420 if (G_UNLIKELY (_inner_error0_ != NULL)) {
421 goto __catch2_g_error;
422 }
423 result = FALSE;
424 _g_free0 (link);
425 return result;
426 }
427 goto __finally2;
428 __catch2_g_error:
429 {
430 g_clear_error (&_inner_error0_);
431 }
432 __finally2:
433 if (G_UNLIKELY (_inner_error0_ != NULL)) {
434 gboolean _tmp26_ = FALSE;
435 _g_free0 (link);
436 g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
437 g_clear_error (&_inner_error0_);
438 return _tmp26_;
439 }
440 {
441 const gchar* _tmp27_;
442 gchar* _tmp28_;
443 gchar* _tmp29_;
444 _tmp27_ = link;
445 _tmp28_ = g_strconcat ("firefox ", _tmp27_, NULL);
446 _tmp29_ = _tmp28_;
447 g_spawn_command_line_async (_tmp29_, &_inner_error0_);
448 _g_free0 (_tmp29_);
449 if (G_UNLIKELY (_inner_error0_ != NULL)) {
450 goto __catch3_g_error;
451 }
452 result = FALSE;
453 _g_free0 (link);
454 return result;
455 }
456 goto __finally3;
457 __catch3_g_error:
458 {
459 g_clear_error (&_inner_error0_);
460 }
461 __finally3:
462 if (G_UNLIKELY (_inner_error0_ != NULL)) {
463 gboolean _tmp30_ = FALSE;
464 _g_free0 (link);
465 g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
466 g_clear_error (&_inner_error0_);
467 return _tmp30_;
468 }
469 g_message ("hypertextview.vala:142: Unable to find an appropriate fallback to open" \
470 " the link");
471 }
472 result = FALSE;
473 _g_free0 (link);
474 return result;
475 }
476
477 /**
478 * motion_notify_event_cb:
479 *
480 * Event to update the cursor of the pointer.
481 */
482 static gboolean
xnp_hypertext_view_motion_notify_event_cb(XnpHypertextView * self,GtkWidget * hypertextview,GdkEventMotion * event)483 xnp_hypertext_view_motion_notify_event_cb (XnpHypertextView* self,
484 GtkWidget* hypertextview,
485 GdkEventMotion* event)
486 {
487 GtkTextIter iter = {0};
488 GdkWindow* win = NULL;
489 gboolean over_link = FALSE;
490 gint x = 0;
491 gint y = 0;
492 gint _tmp0_ = 0;
493 gint _tmp1_ = 0;
494 GtkTextIter _tmp2_ = {0};
495 GtkTextTag* _tmp3_;
496 gboolean result = FALSE;
497 g_return_val_if_fail (self != NULL, FALSE);
498 g_return_val_if_fail (hypertextview != NULL, FALSE);
499 g_return_val_if_fail (event != NULL, FALSE);
500 gtk_text_view_window_to_buffer_coords ((GtkTextView*) self, GTK_TEXT_WINDOW_WIDGET, (gint) event->x, (gint) event->y, &_tmp0_, &_tmp1_);
501 x = _tmp0_;
502 y = _tmp1_;
503 gtk_text_view_get_iter_at_location ((GtkTextView*) self, &_tmp2_, x, y);
504 iter = _tmp2_;
505 _tmp3_ = self->priv->tag_link;
506 over_link = gtk_text_iter_has_tag (&iter, _tmp3_);
507 if (over_link != self->priv->cursor_over_link) {
508 GdkWindow* _tmp4_;
509 GdkWindow* _tmp5_;
510 GdkCursor* _tmp6_ = NULL;
511 GdkWindow* _tmp9_;
512 self->priv->cursor_over_link = over_link;
513 _tmp4_ = gtk_text_view_get_window ((GtkTextView*) self, GTK_TEXT_WINDOW_TEXT);
514 _tmp5_ = _g_object_ref0 (_tmp4_);
515 _g_object_unref0 (win);
516 win = _tmp5_;
517 if (over_link) {
518 GdkCursor* _tmp7_;
519 _tmp7_ = self->priv->hand_cursor;
520 _tmp6_ = _tmp7_;
521 } else {
522 GdkCursor* _tmp8_;
523 _tmp8_ = self->priv->regular_cursor;
524 _tmp6_ = _tmp8_;
525 }
526 _tmp9_ = win;
527 gdk_window_set_cursor (_tmp9_, _tmp6_);
528 }
529 result = FALSE;
530 _g_object_unref0 (win);
531 return result;
532 }
533
534 /**
535 * move_cursor_cb:
536 *
537 * Destroys existing timeouts and executes the actions immediately.
538 */
539 static void
xnp_hypertext_view_move_cursor_cb(XnpHypertextView * self,GtkWidget * hypertextview,GtkMovementStep step,gint count,gboolean extend_selection)540 xnp_hypertext_view_move_cursor_cb (XnpHypertextView* self,
541 GtkWidget* hypertextview,
542 GtkMovementStep step,
543 gint count,
544 gboolean extend_selection)
545 {
546 g_return_if_fail (self != NULL);
547 g_return_if_fail (hypertextview != NULL);
548 if (self->priv->undo_timeout > ((guint) 0)) {
549 GtkTextBuffer* _tmp0_;
550 GtkTextBuffer* _tmp1_;
551 gint _tmp2_;
552 gint _tmp3_;
553 g_source_remove (self->priv->undo_timeout);
554 self->priv->undo_timeout = (guint) 0;
555 xnp_hypertext_view_undo_snapshot (self);
556 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
557 _tmp1_ = _tmp0_;
558 g_object_get (_tmp1_, "cursor-position", &_tmp2_, NULL);
559 _tmp3_ = _tmp2_;
560 self->priv->undo_cursor_pos = _tmp3_;
561 }
562 if (self->priv->tag_timeout > ((guint) 0)) {
563 g_source_remove (self->priv->tag_timeout);
564 self->priv->tag_timeout = (guint) 0;
565 xnp_hypertext_view_update_tags (self);
566 }
567 }
568
569 /**
570 * buffer_changed_cb:
571 *
572 * Initializes timeouts to postpone actions.
573 */
574 static gboolean
_xnp_hypertext_view_undo_snapshot_gsource_func(gpointer self)575 _xnp_hypertext_view_undo_snapshot_gsource_func (gpointer self)
576 {
577 gboolean result;
578 result = xnp_hypertext_view_undo_snapshot ((XnpHypertextView*) self);
579 return result;
580 }
581
582 static gboolean
_xnp_hypertext_view_tag_timeout_cb_gsource_func(gpointer self)583 _xnp_hypertext_view_tag_timeout_cb_gsource_func (gpointer self)
584 {
585 gboolean result;
586 result = xnp_hypertext_view_tag_timeout_cb ((XnpHypertextView*) self);
587 return result;
588 }
589
590 static void
xnp_hypertext_view_buffer_changed_cb(XnpHypertextView * self)591 xnp_hypertext_view_buffer_changed_cb (XnpHypertextView* self)
592 {
593 g_return_if_fail (self != NULL);
594 if (self->priv->undo_timeout > ((guint) 0)) {
595 g_source_remove (self->priv->undo_timeout);
596 self->priv->undo_timeout = (guint) 0;
597 }
598 self->priv->undo_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_undo_snapshot_gsource_func, g_object_ref (self), g_object_unref);
599 if (self->priv->tag_timeout > ((guint) 0)) {
600 g_source_remove (self->priv->tag_timeout);
601 self->priv->tag_timeout = (guint) 0;
602 self->priv->tag_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_tag_timeout_cb_gsource_func, g_object_ref (self), g_object_unref);
603 }
604 }
605
606 /**
607 * insert_text_cb:
608 *
609 * Event to create and update existing tags within the buffer.
610 */
611 static gchar
string_get(const gchar * self,glong index)612 string_get (const gchar* self,
613 glong index)
614 {
615 gchar _tmp0_;
616 gchar result = '\0';
617 g_return_val_if_fail (self != NULL, '\0');
618 _tmp0_ = ((gchar*) self)[index];
619 result = _tmp0_;
620 return result;
621 }
622
623 static gboolean
string_contains(const gchar * self,const gchar * needle)624 string_contains (const gchar* self,
625 const gchar* needle)
626 {
627 gchar* _tmp0_;
628 gboolean result = FALSE;
629 g_return_val_if_fail (self != NULL, FALSE);
630 g_return_val_if_fail (needle != NULL, FALSE);
631 _tmp0_ = strstr ((gchar*) self, (gchar*) needle);
632 result = _tmp0_ != NULL;
633 return result;
634 }
635
636 static void
xnp_hypertext_view_insert_text_cb(XnpHypertextView * self,GtkTextBuffer * buffer,GtkTextIter * location,const gchar * text,gint len)637 xnp_hypertext_view_insert_text_cb (XnpHypertextView* self,
638 GtkTextBuffer* buffer,
639 GtkTextIter* location,
640 const gchar* text,
641 gint len)
642 {
643 GtkTextIter start = {0};
644 GtkTextIter end = {0};
645 GtkTextTag* _tmp0_;
646 g_return_if_fail (self != NULL);
647 g_return_if_fail (buffer != NULL);
648 g_return_if_fail (location != NULL);
649 g_return_if_fail (text != NULL);
650 _tmp0_ = self->priv->tag_link;
651 if (gtk_text_iter_starts_tag (location, _tmp0_)) {
652 gboolean _tmp1_ = FALSE;
653 gint _tmp2_;
654 gint _tmp3_;
655 _tmp2_ = strlen (text);
656 _tmp3_ = _tmp2_;
657 if (string_get (text, (glong) (_tmp3_ - 1)) != ' ') {
658 gint _tmp4_;
659 gint _tmp5_;
660 _tmp4_ = strlen (text);
661 _tmp5_ = _tmp4_;
662 _tmp1_ = string_get (text, (glong) (_tmp5_ - 1)) != '\n';
663 } else {
664 _tmp1_ = FALSE;
665 }
666 if (_tmp1_) {
667 GtkTextIter _tmp6_;
668 GtkTextIter _tmp7_;
669 GtkTextTag* _tmp8_;
670 GtkTextBuffer* _tmp9_;
671 GtkTextBuffer* _tmp10_;
672 GtkTextTag* _tmp11_;
673 GtkTextIter _tmp12_;
674 GtkTextIter _tmp13_;
675 _tmp6_ = *location;
676 start = _tmp6_;
677 _tmp7_ = *location;
678 end = _tmp7_;
679 _tmp8_ = self->priv->tag_link;
680 gtk_text_iter_forward_to_tag_toggle (&end, _tmp8_);
681 _tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) self);
682 _tmp10_ = _tmp9_;
683 _tmp11_ = self->priv->tag_link;
684 _tmp12_ = start;
685 _tmp13_ = end;
686 gtk_text_buffer_remove_tag (_tmp10_, _tmp11_, &_tmp12_, &_tmp13_);
687 }
688 xnp_hypertext_view_tag_timeout_init (self);
689 } else {
690 GtkTextTag* _tmp14_;
691 _tmp14_ = self->priv->tag_link;
692 if (gtk_text_iter_has_tag (location, _tmp14_)) {
693 GtkTextIter _tmp15_;
694 GtkTextTag* _tmp16_;
695 GtkTextIter _tmp17_ = {0};
696 _tmp15_ = *location;
697 start = _tmp15_;
698 _tmp16_ = self->priv->tag_link;
699 gtk_text_iter_backward_to_tag_toggle (&start, _tmp16_);
700 gtk_text_iter_forward_search (&start, "://", GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &_tmp17_, NULL);
701 end = _tmp17_;
702 if (gtk_text_iter_get_offset (location) <= (gtk_text_iter_get_offset (&end) - 3)) {
703 gboolean _tmp18_ = FALSE;
704 if (string_contains (text, " ")) {
705 _tmp18_ = TRUE;
706 } else {
707 _tmp18_ = string_contains (text, "\n");
708 }
709 if (_tmp18_) {
710 GtkTextTag* _tmp19_;
711 GtkTextBuffer* _tmp20_;
712 GtkTextBuffer* _tmp21_;
713 GtkTextTag* _tmp22_;
714 GtkTextIter _tmp23_;
715 GtkTextIter _tmp24_;
716 _tmp19_ = self->priv->tag_link;
717 gtk_text_iter_forward_to_tag_toggle (&end, _tmp19_);
718 _tmp20_ = gtk_text_view_get_buffer ((GtkTextView*) self);
719 _tmp21_ = _tmp20_;
720 _tmp22_ = self->priv->tag_link;
721 _tmp23_ = start;
722 _tmp24_ = end;
723 gtk_text_buffer_remove_tag (_tmp21_, _tmp22_, &_tmp23_, &_tmp24_);
724 xnp_hypertext_view_tag_timeout_init (self);
725 }
726 } else {
727 gboolean _tmp25_ = FALSE;
728 if (gtk_text_iter_get_offset (location) < gtk_text_iter_get_offset (&end)) {
729 _tmp25_ = TRUE;
730 } else {
731 _tmp25_ = string_contains (text, ":");
732 }
733 if (_tmp25_) {
734 GtkTextTag* _tmp26_;
735 GtkTextBuffer* _tmp27_;
736 GtkTextBuffer* _tmp28_;
737 GtkTextTag* _tmp29_;
738 GtkTextIter _tmp30_;
739 GtkTextIter _tmp31_;
740 _tmp26_ = self->priv->tag_link;
741 gtk_text_iter_forward_to_tag_toggle (&end, _tmp26_);
742 _tmp27_ = gtk_text_view_get_buffer ((GtkTextView*) self);
743 _tmp28_ = _tmp27_;
744 _tmp29_ = self->priv->tag_link;
745 _tmp30_ = start;
746 _tmp31_ = end;
747 gtk_text_buffer_remove_tag (_tmp28_, _tmp29_, &_tmp30_, &_tmp31_);
748 } else {
749 gboolean _tmp32_ = FALSE;
750 if (string_contains (text, " ")) {
751 _tmp32_ = TRUE;
752 } else {
753 _tmp32_ = string_contains (text, "\n");
754 }
755 if (_tmp32_) {
756 GtkTextIter _tmp33_;
757 GtkTextTag* _tmp34_;
758 GtkTextBuffer* _tmp35_;
759 GtkTextBuffer* _tmp36_;
760 GtkTextTag* _tmp37_;
761 GtkTextIter _tmp38_;
762 GtkTextIter _tmp39_;
763 _tmp33_ = *location;
764 start = _tmp33_;
765 _tmp34_ = self->priv->tag_link;
766 gtk_text_iter_forward_to_tag_toggle (&end, _tmp34_);
767 _tmp35_ = gtk_text_view_get_buffer ((GtkTextView*) self);
768 _tmp36_ = _tmp35_;
769 _tmp37_ = self->priv->tag_link;
770 _tmp38_ = start;
771 _tmp39_ = end;
772 gtk_text_buffer_remove_tag (_tmp36_, _tmp37_, &_tmp38_, &_tmp39_);
773 xnp_hypertext_view_tag_timeout_init (self);
774 }
775 }
776 }
777 } else {
778 GtkTextTag* _tmp40_;
779 _tmp40_ = self->priv->tag_link;
780 if (gtk_text_iter_ends_tag (location, _tmp40_)) {
781 gboolean _tmp41_ = FALSE;
782 if (len >= 1) {
783 gboolean _tmp42_ = FALSE;
784 if (string_get (text, (glong) 0) == ' ') {
785 _tmp42_ = TRUE;
786 } else {
787 _tmp42_ = string_get (text, (glong) 0) == '\n';
788 }
789 _tmp41_ = !_tmp42_;
790 } else {
791 _tmp41_ = FALSE;
792 }
793 if (_tmp41_) {
794 GtkTextIter _tmp43_;
795 GtkTextTag* _tmp44_;
796 GtkTextBuffer* _tmp45_;
797 GtkTextBuffer* _tmp46_;
798 GtkTextTag* _tmp47_;
799 GtkTextIter _tmp48_;
800 GtkTextIter _tmp49_;
801 _tmp43_ = *location;
802 start = _tmp43_;
803 _tmp44_ = self->priv->tag_link;
804 gtk_text_iter_backward_to_tag_toggle (&start, _tmp44_);
805 _tmp45_ = gtk_text_view_get_buffer ((GtkTextView*) self);
806 _tmp46_ = _tmp45_;
807 _tmp47_ = self->priv->tag_link;
808 _tmp48_ = start;
809 _tmp49_ = *location;
810 gtk_text_buffer_remove_tag (_tmp46_, _tmp47_, &_tmp48_, &_tmp49_);
811 xnp_hypertext_view_tag_timeout_init (self);
812 } else {
813 if (string_contains (text, "://")) {
814 xnp_hypertext_view_tag_timeout_init (self);
815 }
816 }
817 } else {
818 gboolean _tmp50_ = FALSE;
819 if (len == 1) {
820 _tmp50_ = string_get (text, (glong) 0) == '/';
821 } else {
822 _tmp50_ = FALSE;
823 }
824 if (_tmp50_) {
825 GtkTextIter _tmp51_;
826 gboolean _tmp52_ = FALSE;
827 _tmp51_ = *location;
828 start = _tmp51_;
829 if (!gtk_text_iter_backward_chars (&start, 2)) {
830 _tmp52_ = TRUE;
831 } else {
832 GtkTextIter _tmp53_;
833 gchar* _tmp54_;
834 gchar* _tmp55_;
835 _tmp53_ = *location;
836 _tmp54_ = gtk_text_iter_get_text (&start, &_tmp53_);
837 _tmp55_ = _tmp54_;
838 _tmp52_ = g_strcmp0 (_tmp55_, ":/") != 0;
839 _g_free0 (_tmp55_);
840 }
841 if (_tmp52_) {
842 return;
843 }
844 xnp_hypertext_view_tag_timeout_init (self);
845 } else {
846 gboolean _tmp56_ = FALSE;
847 if (len == 1) {
848 gboolean _tmp57_ = FALSE;
849 if (string_get (text, (glong) 0) == ' ') {
850 _tmp57_ = TRUE;
851 } else {
852 _tmp57_ = string_get (text, (glong) 0) == '\n';
853 }
854 _tmp56_ = _tmp57_;
855 } else {
856 _tmp56_ = FALSE;
857 }
858 if (_tmp56_) {
859 xnp_hypertext_view_update_tags (self);
860 } else {
861 gboolean _tmp58_ = FALSE;
862 if (len > 4) {
863 _tmp58_ = string_contains (text, "://");
864 } else {
865 _tmp58_ = FALSE;
866 }
867 if (_tmp58_) {
868 xnp_hypertext_view_tag_timeout_init (self);
869 }
870 }
871 }
872 }
873 }
874 }
875 }
876
877 /**
878 * delete_range_cb:
879 *
880 * Event to delete and update existing tags within the buffer.
881 */
882 static void
xnp_hypertext_view_delete_range_cb(XnpHypertextView * self,GtkTextBuffer * buffer,GtkTextIter * start,GtkTextIter * end)883 xnp_hypertext_view_delete_range_cb (XnpHypertextView* self,
884 GtkTextBuffer* buffer,
885 GtkTextIter* start,
886 GtkTextIter* end)
887 {
888 GtkTextIter iter = {0};
889 gboolean _tmp0_ = FALSE;
890 GtkTextTag* _tmp1_;
891 GtkTextTag* _tmp3_;
892 GtkTextTag* _tmp11_;
893 g_return_if_fail (self != NULL);
894 g_return_if_fail (buffer != NULL);
895 g_return_if_fail (start != NULL);
896 g_return_if_fail (end != NULL);
897 _tmp1_ = self->priv->tag_link;
898 if (!gtk_text_iter_has_tag (start, _tmp1_)) {
899 GtkTextTag* _tmp2_;
900 _tmp2_ = self->priv->tag_link;
901 _tmp0_ = !gtk_text_iter_has_tag (end, _tmp2_);
902 } else {
903 _tmp0_ = FALSE;
904 }
905 if (_tmp0_) {
906 return;
907 }
908 _tmp3_ = self->priv->tag_link;
909 if (gtk_text_iter_has_tag (start, _tmp3_)) {
910 GtkTextIter _tmp4_;
911 GtkTextTag* _tmp5_;
912 GtkTextBuffer* _tmp6_;
913 GtkTextBuffer* _tmp7_;
914 GtkTextTag* _tmp8_;
915 GtkTextIter _tmp9_;
916 GtkTextIter _tmp10_;
917 _tmp4_ = *start;
918 iter = _tmp4_;
919 _tmp5_ = self->priv->tag_link;
920 gtk_text_iter_backward_to_tag_toggle (&iter, _tmp5_);
921 _tmp6_ = gtk_text_view_get_buffer ((GtkTextView*) self);
922 _tmp7_ = _tmp6_;
923 _tmp8_ = self->priv->tag_link;
924 _tmp9_ = iter;
925 _tmp10_ = *start;
926 gtk_text_buffer_remove_tag (_tmp7_, _tmp8_, &_tmp9_, &_tmp10_);
927 }
928 _tmp11_ = self->priv->tag_link;
929 if (gtk_text_iter_has_tag (end, _tmp11_)) {
930 GtkTextIter _tmp12_;
931 GtkTextTag* _tmp13_;
932 GtkTextBuffer* _tmp14_;
933 GtkTextBuffer* _tmp15_;
934 GtkTextTag* _tmp16_;
935 GtkTextIter _tmp17_;
936 GtkTextIter _tmp18_;
937 _tmp12_ = *end;
938 iter = _tmp12_;
939 _tmp13_ = self->priv->tag_link;
940 gtk_text_iter_forward_to_tag_toggle (&iter, _tmp13_);
941 _tmp14_ = gtk_text_view_get_buffer ((GtkTextView*) self);
942 _tmp15_ = _tmp14_;
943 _tmp16_ = self->priv->tag_link;
944 _tmp17_ = *end;
945 _tmp18_ = iter;
946 gtk_text_buffer_remove_tag (_tmp15_, _tmp16_, &_tmp17_, &_tmp18_);
947 }
948 xnp_hypertext_view_tag_timeout_init (self);
949 }
950
951 /**
952 * undo_snapshot:
953 *
954 * Makes a snapshot of the current buffer and swaps undo/redo texts.
955 */
956 static gboolean
xnp_hypertext_view_undo_snapshot(XnpHypertextView * self)957 xnp_hypertext_view_undo_snapshot (XnpHypertextView* self)
958 {
959 GtkTextIter start = {0};
960 GtkTextIter end = {0};
961 GtkTextBuffer* _tmp0_;
962 GtkTextBuffer* _tmp1_;
963 gint _tmp2_;
964 gint _tmp3_;
965 GtkTextBuffer* _tmp4_;
966 GtkTextBuffer* _tmp5_;
967 GtkTextIter _tmp6_ = {0};
968 GtkTextBuffer* _tmp7_;
969 GtkTextBuffer* _tmp8_;
970 GtkTextIter _tmp9_ = {0};
971 const gchar* _tmp10_;
972 gchar* _tmp11_;
973 GtkTextBuffer* _tmp12_;
974 GtkTextBuffer* _tmp13_;
975 GtkTextIter _tmp14_;
976 GtkTextIter _tmp15_;
977 gchar* _tmp16_;
978 gboolean result = FALSE;
979 g_return_val_if_fail (self != NULL, FALSE);
980 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
981 _tmp1_ = _tmp0_;
982 g_object_get (_tmp1_, "cursor-position", &_tmp2_, NULL);
983 _tmp3_ = _tmp2_;
984 self->priv->undo_cursor_pos = _tmp3_;
985 _tmp4_ = gtk_text_view_get_buffer ((GtkTextView*) self);
986 _tmp5_ = _tmp4_;
987 gtk_text_buffer_get_iter_at_offset (_tmp5_, &_tmp6_, 0);
988 start = _tmp6_;
989 _tmp7_ = gtk_text_view_get_buffer ((GtkTextView*) self);
990 _tmp8_ = _tmp7_;
991 gtk_text_buffer_get_iter_at_offset (_tmp8_, &_tmp9_, -1);
992 end = _tmp9_;
993 _tmp10_ = self->priv->redo_text;
994 _tmp11_ = g_strdup (_tmp10_);
995 _g_free0 (self->priv->undo_text);
996 self->priv->undo_text = _tmp11_;
997 _tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
998 _tmp13_ = _tmp12_;
999 _tmp14_ = start;
1000 _tmp15_ = end;
1001 _tmp16_ = gtk_text_buffer_get_text (_tmp13_, &_tmp14_, &_tmp15_, FALSE);
1002 _g_free0 (self->priv->redo_text);
1003 self->priv->redo_text = _tmp16_;
1004 if (self->priv->undo_timeout > ((guint) 0)) {
1005 g_source_remove (self->priv->undo_timeout);
1006 self->priv->undo_timeout = (guint) 0;
1007 }
1008 result = FALSE;
1009 return result;
1010 }
1011
1012 /**
1013 * undo:
1014 *
1015 * Revert the buffer to the undo text and swaps undo/redo texts.
1016 */
1017 void
xnp_hypertext_view_undo(XnpHypertextView * self)1018 xnp_hypertext_view_undo (XnpHypertextView* self)
1019 {
1020 GtkTextIter iter = {0};
1021 GtkTextMark* mark = NULL;
1022 gchar* tmp = NULL;
1023 GtkTextBuffer* _tmp0_;
1024 GtkTextBuffer* _tmp1_;
1025 const gchar* _tmp2_;
1026 GtkTextBuffer* _tmp3_;
1027 GtkTextBuffer* _tmp4_;
1028 GtkTextIter _tmp5_ = {0};
1029 GtkTextBuffer* _tmp6_;
1030 GtkTextBuffer* _tmp7_;
1031 GtkTextIter _tmp8_;
1032 GtkTextBuffer* _tmp9_;
1033 GtkTextBuffer* _tmp10_;
1034 GtkTextMark* _tmp11_;
1035 GtkTextMark* _tmp12_;
1036 GtkTextBuffer* _tmp13_;
1037 GtkTextBuffer* _tmp14_;
1038 GtkTextMark* _tmp15_;
1039 GtkTextIter _tmp16_;
1040 GtkTextMark* _tmp17_;
1041 const gchar* _tmp18_;
1042 gchar* _tmp19_;
1043 const gchar* _tmp20_;
1044 gchar* _tmp21_;
1045 const gchar* _tmp22_;
1046 gchar* _tmp23_;
1047 g_return_if_fail (self != NULL);
1048 if (self->priv->undo_timeout > ((guint) 0)) {
1049 g_source_remove (self->priv->undo_timeout);
1050 self->priv->undo_timeout = (guint) 0;
1051 xnp_hypertext_view_undo_snapshot (self);
1052 }
1053 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1054 _tmp1_ = _tmp0_;
1055 _tmp2_ = self->priv->undo_text;
1056 gtk_text_buffer_set_text (_tmp1_, _tmp2_, -1);
1057 _tmp3_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1058 _tmp4_ = _tmp3_;
1059 gtk_text_buffer_get_iter_at_offset (_tmp4_, &_tmp5_, self->priv->undo_cursor_pos);
1060 iter = _tmp5_;
1061 _tmp6_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1062 _tmp7_ = _tmp6_;
1063 _tmp8_ = iter;
1064 gtk_text_buffer_place_cursor (_tmp7_, &_tmp8_);
1065 _tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1066 _tmp10_ = _tmp9_;
1067 _tmp11_ = gtk_text_buffer_get_mark (_tmp10_, "undo-pos");
1068 _tmp12_ = _g_object_ref0 (_tmp11_);
1069 _g_object_unref0 (mark);
1070 mark = _tmp12_;
1071 _tmp13_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1072 _tmp14_ = _tmp13_;
1073 _tmp15_ = mark;
1074 _tmp16_ = iter;
1075 gtk_text_buffer_move_mark (_tmp14_, _tmp15_, &_tmp16_);
1076 _tmp17_ = mark;
1077 gtk_text_view_scroll_to_mark ((GtkTextView*) self, _tmp17_, 0.0, FALSE, 0.5, 0.5);
1078 _tmp18_ = self->priv->undo_text;
1079 _tmp19_ = g_strdup (_tmp18_);
1080 _g_free0 (tmp);
1081 tmp = _tmp19_;
1082 _tmp20_ = self->priv->redo_text;
1083 _tmp21_ = g_strdup (_tmp20_);
1084 _g_free0 (self->priv->undo_text);
1085 self->priv->undo_text = _tmp21_;
1086 _tmp22_ = tmp;
1087 _tmp23_ = g_strdup (_tmp22_);
1088 _g_free0 (self->priv->redo_text);
1089 self->priv->redo_text = _tmp23_;
1090 if (self->priv->undo_timeout > ((guint) 0)) {
1091 g_source_remove (self->priv->undo_timeout);
1092 self->priv->undo_timeout = (guint) 0;
1093 }
1094 _g_free0 (tmp);
1095 _g_object_unref0 (mark);
1096 }
1097
1098 static gboolean
xnp_hypertext_view_tag_timeout_cb(XnpHypertextView * self)1099 xnp_hypertext_view_tag_timeout_cb (XnpHypertextView* self)
1100 {
1101 gboolean result = FALSE;
1102 g_return_val_if_fail (self != NULL, FALSE);
1103 xnp_hypertext_view_update_tags (self);
1104 result = FALSE;
1105 return result;
1106 }
1107
1108 static void
xnp_hypertext_view_tag_timeout_init(XnpHypertextView * self)1109 xnp_hypertext_view_tag_timeout_init (XnpHypertextView* self)
1110 {
1111 g_return_if_fail (self != NULL);
1112 if (self->priv->tag_timeout > ((guint) 0)) {
1113 g_source_remove (self->priv->tag_timeout);
1114 self->priv->tag_timeout = (guint) 0;
1115 }
1116 self->priv->tag_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_tag_timeout_cb_gsource_func, g_object_ref (self), g_object_unref);
1117 }
1118
1119 /**
1120 * update_tags:
1121 *
1122 * Goes through the entire document to search for untagged links and tag them.
1123 */
1124 void
xnp_hypertext_view_update_tags(XnpHypertextView * self)1125 xnp_hypertext_view_update_tags (XnpHypertextView* self)
1126 {
1127 GtkTextIter iter = {0};
1128 GtkTextIter start = {0};
1129 GtkTextIter end = {0};
1130 GtkTextIter tmp = {0};
1131 gchar* link = NULL;
1132 GtkTextBuffer* _tmp0_;
1133 GtkTextBuffer* _tmp1_;
1134 GtkTextIter _tmp2_ = {0};
1135 g_return_if_fail (self != NULL);
1136 if (self->priv->tag_timeout > ((guint) 0)) {
1137 g_source_remove (self->priv->tag_timeout);
1138 self->priv->tag_timeout = (guint) 0;
1139 }
1140 _tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1141 _tmp1_ = _tmp0_;
1142 gtk_text_buffer_get_iter_at_offset (_tmp1_, &_tmp2_, 0);
1143 iter = _tmp2_;
1144 while (TRUE) {
1145 GtkTextIter _tmp3_ = {0};
1146 GtkTextIter _tmp4_ = {0};
1147 gboolean _tmp5_;
1148 GtkTextIter _tmp6_;
1149 GtkTextTag* _tmp7_;
1150 GtkTextIter _tmp8_ = {0};
1151 gboolean _tmp9_;
1152 _tmp5_ = gtk_text_iter_forward_search (&iter, "://", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp3_, &_tmp4_, NULL);
1153 start = _tmp3_;
1154 end = _tmp4_;
1155 if (!_tmp5_) {
1156 break;
1157 }
1158 _tmp6_ = end;
1159 iter = _tmp6_;
1160 if (!gtk_text_iter_ends_word (&start)) {
1161 continue;
1162 }
1163 gtk_text_iter_backward_word_start (&start);
1164 _tmp7_ = self->priv->tag_link;
1165 if (gtk_text_iter_starts_tag (&start, _tmp7_)) {
1166 continue;
1167 }
1168 _tmp9_ = gtk_text_iter_forward_search (&iter, " ", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp8_, NULL, NULL);
1169 end = _tmp8_;
1170 if (!_tmp9_) {
1171 GtkTextIter _tmp10_ = {0};
1172 gboolean _tmp11_;
1173 _tmp11_ = gtk_text_iter_forward_search (&iter, "\n", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp10_, NULL, NULL);
1174 end = _tmp10_;
1175 if (!_tmp11_) {
1176 GtkTextBuffer* _tmp12_;
1177 GtkTextBuffer* _tmp13_;
1178 GtkTextIter _tmp14_ = {0};
1179 _tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1180 _tmp13_ = _tmp12_;
1181 gtk_text_buffer_get_iter_at_offset (_tmp13_, &_tmp14_, -1);
1182 end = _tmp14_;
1183 }
1184 } else {
1185 GtkTextIter _tmp15_ = {0};
1186 gboolean _tmp16_;
1187 _tmp16_ = gtk_text_iter_forward_search (&iter, "\n", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp15_, NULL, NULL);
1188 tmp = _tmp15_;
1189 if (_tmp16_) {
1190 if (gtk_text_iter_get_offset (&tmp) < gtk_text_iter_get_offset (&end)) {
1191 GtkTextIter _tmp17_;
1192 _tmp17_ = tmp;
1193 end = _tmp17_;
1194 }
1195 }
1196 }
1197 if ((gtk_text_iter_get_offset (&end) - gtk_text_iter_get_offset (&start)) >= 5) {
1198 GtkTextIter _tmp18_;
1199 gchar* _tmp19_;
1200 const gchar* _tmp20_;
1201 GtkTextBuffer* _tmp21_;
1202 GtkTextBuffer* _tmp22_;
1203 GtkTextTag* _tmp23_;
1204 GtkTextIter _tmp24_;
1205 GtkTextIter _tmp25_;
1206 _tmp18_ = end;
1207 _tmp19_ = gtk_text_iter_get_text (&iter, &_tmp18_);
1208 _g_free0 (link);
1209 link = _tmp19_;
1210 _tmp20_ = link;
1211 if (string_contains (_tmp20_, ":")) {
1212 continue;
1213 }
1214 _tmp21_ = gtk_text_view_get_buffer ((GtkTextView*) self);
1215 _tmp22_ = _tmp21_;
1216 _tmp23_ = self->priv->tag_link;
1217 _tmp24_ = start;
1218 _tmp25_ = end;
1219 gtk_text_buffer_apply_tag (_tmp22_, _tmp23_, &_tmp24_, &_tmp25_);
1220 }
1221 }
1222 _g_free0 (link);
1223 }
1224
1225 const gchar*
xnp_hypertext_view_get_font(XnpHypertextView * self)1226 xnp_hypertext_view_get_font (XnpHypertextView* self)
1227 {
1228 const gchar* result;
1229 const gchar* _tmp0_;
1230 g_return_val_if_fail (self != NULL, NULL);
1231 _tmp0_ = self->priv->_font;
1232 result = _tmp0_;
1233 return result;
1234 }
1235
1236 static void
_vala_PangoFontDescription_free(PangoFontDescription * self)1237 _vala_PangoFontDescription_free (PangoFontDescription* self)
1238 {
1239 g_boxed_free (pango_font_description_get_type (), self);
1240 }
1241
1242 void
xnp_hypertext_view_set_font(XnpHypertextView * self,const gchar * value)1243 xnp_hypertext_view_set_font (XnpHypertextView* self,
1244 const gchar* value)
1245 {
1246 gchar* _tmp0_;
1247 PangoFontDescription* font_descr = NULL;
1248 PangoFontDescription* _tmp1_;
1249 g_return_if_fail (self != NULL);
1250 _tmp0_ = g_strdup (value);
1251 _g_free0 (self->priv->_font);
1252 self->priv->_font = _tmp0_;
1253 _tmp1_ = pango_font_description_from_string (value);
1254 font_descr = _tmp1_;
1255 gtk_widget_override_font ((GtkWidget*) self, font_descr);
1256 __vala_PangoFontDescription_free0 (font_descr);
1257 g_object_notify_by_pspec ((GObject *) self, xnp_hypertext_view_properties[XNP_HYPERTEXT_VIEW_FONT_PROPERTY]);
1258 }
1259
1260 static void
_vala_PangoTabArray_free(PangoTabArray * self)1261 _vala_PangoTabArray_free (PangoTabArray* self)
1262 {
1263 g_boxed_free (pango_tab_array_get_type (), self);
1264 }
1265
1266 static GObject *
xnp_hypertext_view_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)1267 xnp_hypertext_view_constructor (GType type,
1268 guint n_construct_properties,
1269 GObjectConstructParam * construct_properties)
1270 {
1271 GObject * obj;
1272 GObjectClass * parent_class;
1273 XnpHypertextView * self;
1274 PangoTabArray* _tmp0_;
1275 PangoTabArray* _tmp1_;
1276 parent_class = G_OBJECT_CLASS (xnp_hypertext_view_parent_class);
1277 obj = parent_class->constructor (type, n_construct_properties, construct_properties);
1278 self = G_TYPE_CHECK_INSTANCE_CAST (obj, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
1279 xnp_hypertext_view_set_font (self, "Sans 13");
1280 _tmp0_ = pango_tab_array_new_with_positions (1, TRUE, PANGO_TAB_LEFT, 12, NULL);
1281 _tmp1_ = _tmp0_;
1282 gtk_text_view_set_tabs ((GtkTextView*) self, _tmp1_);
1283 __vala_PangoTabArray_free0 (_tmp1_);
1284 return obj;
1285 }
1286
1287 static void
xnp_hypertext_view_class_init(XnpHypertextViewClass * klass,gpointer klass_data)1288 xnp_hypertext_view_class_init (XnpHypertextViewClass * klass,
1289 gpointer klass_data)
1290 {
1291 xnp_hypertext_view_parent_class = g_type_class_peek_parent (klass);
1292 g_type_class_adjust_private_offset (klass, &XnpHypertextView_private_offset);
1293 G_OBJECT_CLASS (klass)->get_property = _vala_xnp_hypertext_view_get_property;
1294 G_OBJECT_CLASS (klass)->set_property = _vala_xnp_hypertext_view_set_property;
1295 G_OBJECT_CLASS (klass)->constructor = xnp_hypertext_view_constructor;
1296 G_OBJECT_CLASS (klass)->finalize = xnp_hypertext_view_finalize;
1297 g_object_class_install_property (G_OBJECT_CLASS (klass), XNP_HYPERTEXT_VIEW_FONT_PROPERTY, xnp_hypertext_view_properties[XNP_HYPERTEXT_VIEW_FONT_PROPERTY] = g_param_spec_string ("font", "font", "font", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
1298 }
1299
1300 static void
xnp_hypertext_view_instance_init(XnpHypertextView * self,gpointer klass)1301 xnp_hypertext_view_instance_init (XnpHypertextView * self,
1302 gpointer klass)
1303 {
1304 GdkDisplay* _tmp0_;
1305 GdkCursor* _tmp1_;
1306 GdkDisplay* _tmp2_;
1307 GdkCursor* _tmp3_;
1308 gchar* _tmp4_;
1309 gchar* _tmp5_;
1310 self->priv = xnp_hypertext_view_get_instance_private (self);
1311 _tmp0_ = gdk_display_get_default ();
1312 _tmp1_ = gdk_cursor_new_for_display (_tmp0_, GDK_HAND2);
1313 self->priv->hand_cursor = _tmp1_;
1314 _tmp2_ = gdk_display_get_default ();
1315 _tmp3_ = gdk_cursor_new_for_display (_tmp2_, GDK_XTERM);
1316 self->priv->regular_cursor = _tmp3_;
1317 self->priv->cursor_over_link = FALSE;
1318 self->priv->undo_timeout = (guint) 0;
1319 _tmp4_ = g_strdup ("");
1320 self->priv->undo_text = _tmp4_;
1321 _tmp5_ = g_strdup ("");
1322 self->priv->redo_text = _tmp5_;
1323 self->priv->tag_timeout = (guint) 0;
1324 }
1325
1326 static void
xnp_hypertext_view_finalize(GObject * obj)1327 xnp_hypertext_view_finalize (GObject * obj)
1328 {
1329 XnpHypertextView * self;
1330 self = G_TYPE_CHECK_INSTANCE_CAST (obj, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
1331 if (self->priv->undo_timeout != ((guint) 0)) {
1332 g_source_remove (self->priv->undo_timeout);
1333 }
1334 if (self->priv->tag_timeout != ((guint) 0)) {
1335 g_source_remove (self->priv->tag_timeout);
1336 }
1337 _g_object_unref0 (self->priv->hand_cursor);
1338 _g_object_unref0 (self->priv->regular_cursor);
1339 _g_free0 (self->priv->undo_text);
1340 _g_free0 (self->priv->redo_text);
1341 _g_object_unref0 (self->priv->tag_link);
1342 _g_free0 (self->priv->_font);
1343 G_OBJECT_CLASS (xnp_hypertext_view_parent_class)->finalize (obj);
1344 }
1345
1346 static GType
xnp_hypertext_view_get_type_once(void)1347 xnp_hypertext_view_get_type_once (void)
1348 {
1349 static const GTypeInfo g_define_type_info = { sizeof (XnpHypertextViewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) xnp_hypertext_view_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (XnpHypertextView), 0, (GInstanceInitFunc) xnp_hypertext_view_instance_init, NULL };
1350 GType xnp_hypertext_view_type_id;
1351 xnp_hypertext_view_type_id = g_type_register_static (gtk_text_view_get_type (), "XnpHypertextView", &g_define_type_info, 0);
1352 XnpHypertextView_private_offset = g_type_add_instance_private (xnp_hypertext_view_type_id, sizeof (XnpHypertextViewPrivate));
1353 return xnp_hypertext_view_type_id;
1354 }
1355
1356 GType
xnp_hypertext_view_get_type(void)1357 xnp_hypertext_view_get_type (void)
1358 {
1359 static volatile gsize xnp_hypertext_view_type_id__volatile = 0;
1360 if (g_once_init_enter (&xnp_hypertext_view_type_id__volatile)) {
1361 GType xnp_hypertext_view_type_id;
1362 xnp_hypertext_view_type_id = xnp_hypertext_view_get_type_once ();
1363 g_once_init_leave (&xnp_hypertext_view_type_id__volatile, xnp_hypertext_view_type_id);
1364 }
1365 return xnp_hypertext_view_type_id__volatile;
1366 }
1367
1368 static void
_vala_xnp_hypertext_view_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)1369 _vala_xnp_hypertext_view_get_property (GObject * object,
1370 guint property_id,
1371 GValue * value,
1372 GParamSpec * pspec)
1373 {
1374 XnpHypertextView * self;
1375 self = G_TYPE_CHECK_INSTANCE_CAST (object, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
1376 switch (property_id) {
1377 case XNP_HYPERTEXT_VIEW_FONT_PROPERTY:
1378 g_value_set_string (value, xnp_hypertext_view_get_font (self));
1379 break;
1380 default:
1381 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1382 break;
1383 }
1384 }
1385
1386 static void
_vala_xnp_hypertext_view_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)1387 _vala_xnp_hypertext_view_set_property (GObject * object,
1388 guint property_id,
1389 const GValue * value,
1390 GParamSpec * pspec)
1391 {
1392 XnpHypertextView * self;
1393 self = G_TYPE_CHECK_INSTANCE_CAST (object, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
1394 switch (property_id) {
1395 case XNP_HYPERTEXT_VIEW_FONT_PROPERTY:
1396 xnp_hypertext_view_set_font (self, g_value_get_string (value));
1397 break;
1398 default:
1399 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1400 break;
1401 }
1402 }
1403
1404