From 72400426284b2d937db39c5623eaa04ca704a77d Mon Sep 17 00:00:00 2001 From: igor montagner Date: Sat, 6 Mar 2021 17:42:20 -0300 Subject: [PATCH 1/2] First version: links in event descriptions are clickable. --- src/EventEdition/InfoPanel.vala | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/EventEdition/InfoPanel.vala b/src/EventEdition/InfoPanel.vala index 9bbdaee59..bd18402df 100644 --- a/src/EventEdition/InfoPanel.vala +++ b/src/EventEdition/InfoPanel.vala @@ -264,6 +264,30 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { Gtk.TextBuffer buffer = new Gtk.TextBuffer (null); buffer.text = property.get_comment (); comment_textview.set_buffer (buffer); + + var r = new GLib.Regex("https?://[\\w.-]*(\\/[\\w-\\d]*)*"); + var link_tag = buffer.create_tag ("link"); + link_tag.event.connect (on_link_clicked); + link_tag.set_property ("foreground", "#0000FF"); + link_tag.underline = Pango.Underline.SINGLE; + GLib.MatchInfo mi; + + Gtk.TextIter search_iter; + buffer.get_start_iter (out search_iter); + if (r.match(buffer.text, 0, out mi)) { + do { + int start, end; + mi.fetch_pos (0, out start, out end); + var link_text = buffer.text.substring(start, end - start); + + Gtk.TextIter starti, endi; + search_iter.forward_search (link_text, Gtk.TextSearchFlags.TEXT_ONLY, out starti, out endi, null); + + buffer.apply_tag (link_tag, starti, endi); + search_iter.forward_chars (link_text.length); + } while (mi.next()); + } + } // Load the source @@ -299,6 +323,28 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { } } + bool on_link_clicked (Gtk.TextTag tag, GLib.Object unused, Gdk.Event event, Gtk.TextIter iter) { + Gdk.ModifierType state; + event.get_state (out state); + var control = (state & Gdk.ModifierType.CONTROL_MASK) != 0; + if (event.type == Gdk.EventType.BUTTON_RELEASE && + control) { + var button_event = (Gdk.EventButton) event; + if (button_event.button == Gdk.BUTTON_PRIMARY) { + var start = iter.copy (); + start.backward_to_tag_toggle (tag); + + iter.forward_to_tag_toggle (tag); + + var s = comment_textview.buffer.get_text (start, iter, false); + Gtk.show_uri_on_window (null, s, Gdk.CURRENT_TIME); + return true; + } + } + + return false; + } + Granite.Widgets.DatePicker make_date_picker () { var format = Granite.DateTime.get_default_date_format (false, true, true); var date_picker = new Granite.Widgets.DatePicker.with_format (format); From 04f3cb6c5a2c9e6b969b8467756f116f4098e0eb Mon Sep 17 00:00:00 2001 From: igor montagner Date: Sun, 7 Mar 2021 16:53:36 -0300 Subject: [PATCH 2/2] Cursor changes to hand when pointing a link. --- src/EventEdition/InfoPanel.vala | 49 +++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/EventEdition/InfoPanel.vala b/src/EventEdition/InfoPanel.vala index bd18402df..f53e46785 100644 --- a/src/EventEdition/InfoPanel.vala +++ b/src/EventEdition/InfoPanel.vala @@ -21,6 +21,7 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { private Gtk.Entry title_entry; private Gtk.TextView comment_textview; + private Gtk.TextTag? comment_link_tag; private Granite.Widgets.DatePicker from_date_picker; private Granite.Widgets.DatePicker to_date_picker; private Gtk.Switch allday_switch; @@ -145,6 +146,26 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { comment_textview.set_border_window_size (Gtk.TextWindowType.TOP, 2); comment_textview.set_border_window_size (Gtk.TextWindowType.BOTTOM, 2); + // Change cursor to hand when pointing a link when CTRL is pressed + comment_textview.motion_notify_event.connect ((event) => { + if (comment_link_tag != null) { + Gtk.TextIter pointed_at; + int buffer_x, buffer_y; + comment_textview.window_to_buffer_coords (Gtk.TextWindowType.WIDGET, (int) event.x, (int) event.y, out buffer_x, out buffer_y); + comment_textview.get_iter_at_location (out pointed_at, buffer_x, buffer_y); + + var control = event.state & Gdk.ModifierType.CONTROL_MASK; + if (pointed_at.has_tag (comment_link_tag) && control != 0) { + var hand = new Gdk.Cursor.from_name (comment_textview.get_display (), "hand"); + event.window.set_cursor (hand); + } else { + var hand = new Gdk.Cursor.from_name (comment_textview.get_display (), "text"); + event.window.set_cursor (hand); + } + } + return false; + }); + var scrolled = new Gtk.ScrolledWindow (null, null); scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER; scrolled.add (comment_textview); @@ -265,27 +286,28 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { buffer.text = property.get_comment (); comment_textview.set_buffer (buffer); - var r = new GLib.Regex("https?://[\\w.-]*(\\/[\\w-\\d]*)*"); - var link_tag = buffer.create_tag ("link"); - link_tag.event.connect (on_link_clicked); - link_tag.set_property ("foreground", "#0000FF"); - link_tag.underline = Pango.Underline.SINGLE; + // Identify links in the description and apply a tag to style them + var link_regex = new GLib.Regex ("https?://[\\w.-]*(\\/[\\w-\\d]*)*"); + comment_link_tag = buffer.create_tag ("link"); + comment_link_tag.event.connect (on_link_clicked); + comment_link_tag.set_property ("foreground", "#0000FF"); + comment_link_tag.underline = Pango.Underline.SINGLE; GLib.MatchInfo mi; Gtk.TextIter search_iter; buffer.get_start_iter (out search_iter); - if (r.match(buffer.text, 0, out mi)) { + if (link_regex.match (buffer.text, 0, out mi)) { do { int start, end; mi.fetch_pos (0, out start, out end); - var link_text = buffer.text.substring(start, end - start); + var link_text = buffer.text.substring (start, end - start); Gtk.TextIter starti, endi; search_iter.forward_search (link_text, Gtk.TextSearchFlags.TEXT_ONLY, out starti, out endi, null); - buffer.apply_tag (link_tag, starti, endi); + buffer.apply_tag (comment_link_tag, starti, endi); search_iter.forward_chars (link_text.length); - } while (mi.next()); + } while (mi.next ()); } } @@ -327,20 +349,19 @@ public class Maya.View.EventEdition.InfoPanel : Gtk.Grid { Gdk.ModifierType state; event.get_state (out state); var control = (state & Gdk.ModifierType.CONTROL_MASK) != 0; - if (event.type == Gdk.EventType.BUTTON_RELEASE && + if (event.type == Gdk.EventType.BUTTON_RELEASE && control) { var button_event = (Gdk.EventButton) event; if (button_event.button == Gdk.BUTTON_PRIMARY) { var start = iter.copy (); start.backward_to_tag_toggle (tag); - iter.forward_to_tag_toggle (tag); - var s = comment_textview.buffer.get_text (start, iter, false); - Gtk.show_uri_on_window (null, s, Gdk.CURRENT_TIME); + var link_dst = comment_textview.buffer.get_text (start, iter, false); + Gtk.show_uri_on_window (null, link_dst, Gdk.CURRENT_TIME); return true; } - } + } return false; }