diff --git a/libgitg/gitg-diff-view-file.vala b/libgitg/gitg-diff-view-file.vala index 63bcc354..1d4dc002 100644 --- a/libgitg/gitg-diff-view-file.vala +++ b/libgitg/gitg-diff-view-file.vala @@ -154,6 +154,111 @@ class Gitg.DiffViewFile : Gtk.Grid } d_expander.bind_property("expanded", this, "expanded", BindingFlags.BIDIRECTIONAL); + + if (repository != null && !repository.is_bare) + { + d_expander.popup_menu.connect(expander_popup_menu); + d_expander.button_press_event.connect(expander_button_press_event); + } + } + + private void show_popup(Gdk.EventButton? event) + { + var menu = new Gtk.Menu(); + + var oldpath = delta.get_old_file().get_path(); + var newpath = delta.get_new_file().get_path(); + + var open_file = new Gtk.MenuItem.with_mnemonic(_("_Open file")); + open_file.show(); + + File? location = null; + + if (newpath != null && newpath != "") + { + location = repository.get_workdir().get_child(newpath); + } + else if (oldpath != null && oldpath != "") + { + location = repository.get_workdir().get_child(oldpath); + } + + if (location == null) + { + return; + } + + open_file.activate.connect(() => { + try + { + Gtk.show_uri(d_expander.get_screen(), location.get_uri(), Gdk.CURRENT_TIME); + } + catch (Error e) + { + stderr.printf(@"Failed to open file: $(e.message)\n"); + } + }); + + menu.add(open_file); + + var open_folder = new Gtk.MenuItem.with_mnemonic(_("Open containing _folder")); + open_folder.show(); + + open_folder.activate.connect(() => { + try + { + Gtk.show_uri(d_expander.get_screen(), location.get_parent().get_uri(), Gdk.CURRENT_TIME); + } + catch (Error e) + { + stderr.printf(@"Failed to open folder: $(e.message)\n"); + } + }); + + menu.add(open_folder); + + var separator = new Gtk.SeparatorMenuItem(); + separator.show(); + menu.add(separator); + + var copy_file_path = new Gtk.MenuItem.with_mnemonic(_("_Copy file path")); + copy_file_path.show(); + + copy_file_path.activate.connect(() => { + var clip = d_expander.get_clipboard(Gdk.SELECTION_CLIPBOARD); + clip.set_text(location.get_path(), -1); + }); + + menu.add(copy_file_path); + + uint button = 0; + uint evtime = Gdk.CURRENT_TIME; + + if (event != null) + { + button = event.button; + evtime = event.time; + } + + menu.attach_to_widget(d_expander, null); + menu.popup(null, null, null, button, evtime); + } + + private bool expander_button_press_event(Gtk.Widget widget, Gdk.EventButton? event) + { + if (event.triggers_context_menu()) + { + show_popup(event); + return true; + } + + return false; + } + + private bool expander_popup_menu(Gtk.Widget widget) + { + show_popup(null); + return true; } public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList lines) diff --git a/po/POTFILES.in b/po/POTFILES.in index 66d056c6..168dddc9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -35,6 +35,7 @@ gitg/preferences/gitg-preferences-interface.vala libgitg/gitg-authentication-dialog.vala libgitg/gitg-date.vala libgitg/gitg-diff-view-commit-details.vala +libgitg/gitg-diff-view-file.vala libgitg/gitg-diff-view.vala libgitg/gitg-repository-list-box.vala libgitg/gitg-stage.vala diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 9f250c49..87e7c0da 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -33,8 +33,9 @@ gitg/preferences/gitg-preferences-interface.c libgitg/gitg-authentication-dialog.c libgitg/gitg-authentication-dialog.c libgitg/gitg-date.c -libgitg/gitg-diff-view.c libgitg/gitg-diff-view-commit-details.c +libgitg/gitg-diff-view-file.c +libgitg/gitg-diff-view.c libgitg/gitg-repository-list-box.c libgitg/gitg-stage.c plugins/diff/gitg-diff.c