dino/main/src/ui/conversation_summary/message_textview.vala

87 lines
3.2 KiB
Vala
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Gdk;
using Gtk;
using Dino.Entities;
namespace Dino.Ui.ConversationSummary {
public class MessageTextView : TextView {
private TextTag link_tag;
public MessageTextView() {
Object(editable:false, hexpand:true, wrap_mode:WrapMode.WORD_CHAR);
link_tag = buffer.create_tag("url", underline: Pango.Underline.SINGLE, foreground: "blue");
button_release_event.connect(open_url);
motion_notify_event.connect(change_cursor_over_url);
update_display_style();
Util.force_base_background(this, "textview, text:not(:selected)");
style_updated.connect(update_display_style);
}
public void add_text(string text) {
TextIter end;
buffer.get_end_iter(out end);
buffer.insert(ref end, text, -1);
format_suffix_urls(text);
}
private void update_display_style() {
LinkButton lnk = new LinkButton("http://example.com");
RGBA link_color = lnk.get_style_context().get_color(StateFlags.LINK);
link_tag.foreground_rgba = link_color;
}
private void format_suffix_urls(string text) {
int absolute_start = buffer.text.length - text.length;
Regex url_regex = new Regex("""(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»]))""");
MatchInfo match_info;
url_regex.match(text, 0, out match_info);
for (; match_info.matches(); match_info.next()) {
string? url = match_info.fetch(0);
int start;
int end;
match_info.fetch_pos(0, out start, out end);
start = text[0:start].char_count();
end = text[0:end].char_count();
TextIter start_iter;
TextIter end_iter;
buffer.get_iter_at_offset(out start_iter, absolute_start + start);
buffer.get_iter_at_offset(out end_iter, absolute_start + end);
buffer.apply_tag_by_name("url", start_iter, end_iter);
}
}
private bool open_url(EventButton event_button) {
int buffer_x, buffer_y;
window_to_buffer_coords(TextWindowType.TEXT, (int) event_button.x, (int) event_button.y, out buffer_x, out buffer_y);
TextIter iter;
get_iter_at_location(out iter, buffer_x, buffer_y);
TextIter start_iter = iter, end_iter = iter;
if (start_iter.backward_to_tag_toggle(null) && end_iter.forward_to_tag_toggle(null)) {
string url = start_iter.get_text(end_iter);
try{
AppInfo.launch_default_for_uri(url, null);
} catch (Error err) {
print("Tryed to open " + url);
}
}
return false;
}
private bool change_cursor_over_url(EventMotion event_motion) {
TextIter iter;
get_iter_at_location(out iter, (int) event_motion.x, (int) event_motion.y);
if (iter.has_tag(buffer.tag_table.lookup("url"))) {
event_motion.window.set_cursor(new Cursor.for_display(get_display(), CursorType.HAND2));
} else {
event_motion.window.set_cursor(new Cursor.for_display(get_display(), CursorType.XTERM));
}
return false;
}
}
}