Repopulate message TextView context menu, include "Copy URL" (#219)

* Add "Copy URL" context menu option when hovering over a URL

* Update message_textview.vala
This commit is contained in:
Yussuf Khalil 2017-12-05 15:06:31 +01:00 committed by fiaxh
parent cee39b0117
commit dc2dde5378

View file

@ -13,12 +13,18 @@ public class MessageTextView : TextView {
Object(editable:false, hexpand:true, wrap_mode:WrapMode.WORD_CHAR); Object(editable:false, hexpand:true, wrap_mode:WrapMode.WORD_CHAR);
link_tag = buffer.create_tag("url", underline: Pango.Underline.SINGLE, foreground: "blue"); link_tag = buffer.create_tag("url", underline: Pango.Underline.SINGLE, foreground: "blue");
button_release_event.connect(open_url); button_release_event.connect((event_button) => {
if (event_button.button == 1) {
open_url(event_button);
}
return false;
});
motion_notify_event.connect(change_cursor_over_url); motion_notify_event.connect(change_cursor_over_url);
update_display_style(); update_display_style();
Util.force_base_background(this, "textview, text:not(:selected)"); Util.force_base_background(this, "textview, text:not(:selected)");
style_updated.connect(update_display_style); style_updated.connect(update_display_style);
populate_popup.connect(populate_context_menu);
} }
// Workaround GTK TextView issues // Workaround GTK TextView issues
@ -44,6 +50,45 @@ public class MessageTextView : TextView {
link_tag.foreground_rgba = link_color; link_tag.foreground_rgba = link_color;
} }
private string? find_url_at_location(int x, int y) {
TextIter iter;
get_iter_at_location(out iter, x, y);
TextIter start_iter = iter, end_iter = iter;
if (start_iter.backward_to_tag_toggle(null) && end_iter.forward_to_tag_toggle(null)) {
return start_iter.get_text(end_iter);
}
return null;
}
private void populate_context_menu(Gtk.Menu popup) {
popup.@foreach((widget) => { widget.destroy(); });
Gdk.Window window = get_window(TextWindowType.TEXT);
List<weak Seat> seats = window.get_display().list_seats();
if (seats.length() > 0) {
int device_x, device_y;
window.get_device_position(seats.nth_data(0).get_pointer(), out device_x, out device_y, null);
string url = find_url_at_location(device_x, device_y);
if (url != null) {
Gtk.MenuItem copy_url_item = new Gtk.MenuItem.with_label(_("Copy Link Address")) { visible=true };
copy_url_item.activate.connect(() => {
Clipboard.get_default(window.get_display()).set_text(url, url.length);
});
popup.append(copy_url_item);
}
}
Gtk.MenuItem copy_item = new Gtk.MenuItem.with_label(_("Copy")) { visible=true };
copy_item.sensitive = buffer.get_has_selection();
copy_item.activate.connect(() => this.copy_clipboard() );
popup.append(copy_item);
Gtk.MenuItem select_all_item = new Gtk.MenuItem.with_label(_("Select All")) { visible=true };
select_all_item.activate.connect(() => this.select_all(true) );
popup.append(select_all_item);
}
private void format_suffix_urls(string text) { private void format_suffix_urls(string text) {
int absolute_start = buffer.text.char_count() - text.char_count(); int absolute_start = buffer.text.char_count() - text.char_count();
@ -67,11 +112,8 @@ public class MessageTextView : TextView {
private bool open_url(EventButton event_button) { private bool open_url(EventButton event_button) {
int buffer_x, buffer_y; 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); window_to_buffer_coords(TextWindowType.TEXT, (int) event_button.x, (int) event_button.y, out buffer_x, out buffer_y);
TextIter iter; string url = find_url_at_location(buffer_x, buffer_y);
get_iter_at_location(out iter, buffer_x, buffer_y); if (url != null) {
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{ try{
AppInfo.launch_default_for_uri(url, null); AppInfo.launch_default_for_uri(url, null);
} catch (Error err) { } catch (Error err) {