mirror of
https://gitlab.gnome.org/GNOME/gitg
synced 2024-10-04 06:59:25 +00:00
Cleanly separate ref actions using interfaces
This commit is contained in:
parent
456da855b2
commit
3750ed9fd0
|
@ -57,6 +57,7 @@ gitg_gitg_VALASOURCES = \
|
|||
gitg/gitg-resource.vala \
|
||||
gitg/gitg-application.vala \
|
||||
gitg/gitg-plugins-engine.vala \
|
||||
gitg/gitg-popup-menu.vala \
|
||||
gitg/gitg-ui-elements.vala \
|
||||
gitg/gitg-ref-action-rename.vala \
|
||||
gitg/gitg-ref-action-delete.vala \
|
||||
|
@ -65,6 +66,7 @@ gitg_gitg_VALASOURCES = \
|
|||
gitg/preferences/gitg-preferences-interface.vala \
|
||||
gitg/preferences/gitg-preferences-history.vala \
|
||||
gitg/history/gitg-history.vala \
|
||||
gitg/history/gitg-history-action-interface.vala \
|
||||
gitg/history/gitg-history-refs-list.vala \
|
||||
gitg/history/gitg-history-paned.vala \
|
||||
gitg/commit/gitg-commit.vala \
|
||||
|
|
86
gitg/gitg-popup-menu.vala
Normal file
86
gitg/gitg-popup-menu.vala
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* This file is part of gitg
|
||||
*
|
||||
* Copyright (C) 2014 - Jesse van den Kieboom
|
||||
*
|
||||
* gitg is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gitg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with gitg. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Gitg
|
||||
{
|
||||
|
||||
class PopupMenu : Object
|
||||
{
|
||||
public signal Gtk.Menu? populate_menu(Gdk.EventButton? event);
|
||||
|
||||
private Gtk.Widget? d_widget;
|
||||
|
||||
public PopupMenu(Gtk.Widget widget)
|
||||
{
|
||||
widget.button_press_event.connect(on_button_press_event);
|
||||
widget.popup_menu.connect(on_popup_menu);
|
||||
|
||||
d_widget = widget;
|
||||
}
|
||||
|
||||
public override void dispose()
|
||||
{
|
||||
if (d_widget != null)
|
||||
{
|
||||
d_widget.button_press_event.disconnect(on_button_press_event);
|
||||
d_widget.popup_menu.disconnect(on_popup_menu);
|
||||
|
||||
d_widget = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool popup_menu(Gtk.Widget widget, Gdk.EventButton? event)
|
||||
{
|
||||
var menu = populate_menu(event);
|
||||
|
||||
if (menu == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var time = (event == null ? Gtk.get_current_event_time() : event.time);
|
||||
var button = (event == null ? 0 : event.button);
|
||||
|
||||
menu.attach_to_widget(widget, null);
|
||||
menu.popup(null, null, null, button, time);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool on_popup_menu(Gtk.Widget widget)
|
||||
{
|
||||
return popup_menu(widget, null);
|
||||
}
|
||||
|
||||
private bool on_button_press_event(Gtk.Widget widget, Gdk.EventButton event)
|
||||
{
|
||||
Gdk.Event *ev = (Gdk.Event *)(&event);
|
||||
|
||||
if (!ev->triggers_context_menu())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return popup_menu(widget, event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ex:set ts=4 noet
|
|
@ -25,10 +25,10 @@ class RefActionDelete : GitgExt.Action, GitgExt.RefAction, Object
|
|||
// Do this to pull in config.h before glib.h (for gettext...)
|
||||
private const string version = Gitg.Config.VERSION;
|
||||
|
||||
public GitgExt.ActionInterface action_interface { get; construct set; }
|
||||
public Ggit.Ref reference { get; construct set; }
|
||||
public GitgExt.RefActionInterface action_interface { get; construct set; }
|
||||
public Gitg.Ref reference { get; construct set; }
|
||||
|
||||
public RefActionDelete(GitgExt.ActionInterface action_interface, Ggit.Ref reference)
|
||||
public RefActionDelete(GitgExt.RefActionInterface action_interface, Gitg.Ref reference)
|
||||
{
|
||||
Object(action_interface: action_interface, reference: reference);
|
||||
}
|
||||
|
@ -42,12 +42,9 @@ class RefActionDelete : GitgExt.Action, GitgExt.RefAction, Object
|
|||
{
|
||||
get
|
||||
{
|
||||
var r = reference as Gitg.Ref;
|
||||
var rtype = r.parsed_name.rtype;
|
||||
|
||||
return rtype == RefType.BRANCH
|
||||
|| rtype == RefType.TAG
|
||||
|| rtype == RefType.REMOTE;
|
||||
return reference.is_branch()
|
||||
|| reference.is_tag()
|
||||
|| reference.is_remote();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ class RefActionRename : GitgExt.Action, GitgExt.RefAction, Object
|
|||
// Do this to pull in config.h before glib.h (for gettext...)
|
||||
private const string version = Gitg.Config.VERSION;
|
||||
|
||||
public GitgExt.ActionInterface action_interface { get; construct set; }
|
||||
public Ggit.Ref reference { get; construct set; }
|
||||
public GitgExt.RefActionInterface action_interface { get; construct set; }
|
||||
public Gitg.Ref reference { get; construct set; }
|
||||
|
||||
public RefActionRename(GitgExt.ActionInterface action_interface, Ggit.Ref reference)
|
||||
public RefActionRename(GitgExt.RefActionInterface action_interface, Gitg.Ref reference)
|
||||
{
|
||||
Object(action_interface: action_interface, reference: reference);
|
||||
}
|
||||
|
@ -47,12 +47,81 @@ class RefActionRename : GitgExt.Action, GitgExt.RefAction, Object
|
|||
{
|
||||
get
|
||||
{
|
||||
var r = reference as Gitg.Ref;
|
||||
var rtype = r.parsed_name.rtype;
|
||||
|
||||
return rtype == RefType.BRANCH || rtype == RefType.TAG;
|
||||
return reference.is_branch()
|
||||
|| reference.is_tag();
|
||||
}
|
||||
}
|
||||
|
||||
public void activated()
|
||||
{
|
||||
action_interface.edit_ref_name(reference, on_ref_name_editing_done);
|
||||
}
|
||||
|
||||
private void on_ref_name_editing_done(string new_text, bool cancelled)
|
||||
{
|
||||
if (cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string orig;
|
||||
string? prefix;
|
||||
|
||||
var pn = reference.parsed_name;
|
||||
|
||||
if (pn.rtype == Gitg.RefType.REMOTE)
|
||||
{
|
||||
orig = pn.remote_branch;
|
||||
prefix = pn.prefix + "/" + pn.remote_name + "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
orig = pn.shortname;
|
||||
prefix = pn.prefix;
|
||||
}
|
||||
|
||||
if (orig == new_text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Ggit.Ref.is_valid_name(@"$prefix$new_text"))
|
||||
{
|
||||
var msg = _("The specified name ‘%s’ contains invalid characters").printf(new_text);
|
||||
|
||||
action_interface.application.show_infobar(_("Invalid name"),
|
||||
msg,
|
||||
Gtk.MessageType.ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var branch = reference as Ggit.Branch;
|
||||
Gitg.Ref? new_ref = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (branch != null)
|
||||
{
|
||||
new_ref = branch.move(new_text, Ggit.CreateFlags.NONE) as Gitg.Ref;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ref = reference.rename(new_text, false) as Gitg.Ref;
|
||||
}
|
||||
}
|
||||
catch (Error e)
|
||||
{
|
||||
action_interface.application.show_infobar(_("Failed to rename"),
|
||||
e.message,
|
||||
Gtk.MessageType.ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
action_interface.application.repository.clear_refs_cache();
|
||||
action_interface.replace_ref(reference, new_ref);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Gitg
|
|||
{
|
||||
|
||||
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-window.ui")]
|
||||
public class Window : Gtk.ApplicationWindow, GitgExt.Application, GitgExt.ActionInterface, Initable
|
||||
public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
|
||||
{
|
||||
private Settings d_state_settings;
|
||||
private Settings d_interface_settings;
|
||||
|
@ -648,11 +648,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, GitgExt.Action
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GitgExt.ActionInterface action_interface
|
||||
{
|
||||
owned get { return this; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
64
gitg/history/gitg-history-action-interface.vala
Normal file
64
gitg/history/gitg-history-action-interface.vala
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This file is part of gitg
|
||||
*
|
||||
* Copyright (C) 2014 - Jesse van den Kieboom
|
||||
*
|
||||
* gitg is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gitg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with gitg. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace GitgHistory
|
||||
{
|
||||
|
||||
class ActionInterface : Object, GitgExt.RefActionInterface
|
||||
{
|
||||
public GitgExt.Application application { owned get; construct set; }
|
||||
|
||||
private RefsList d_refs_list;
|
||||
|
||||
public ActionInterface(GitgExt.Application application, RefsList refs_list)
|
||||
{
|
||||
Object(application: application);
|
||||
|
||||
d_refs_list = refs_list;
|
||||
}
|
||||
|
||||
public void add_ref(Gitg.Ref reference)
|
||||
{
|
||||
d_refs_list.add_ref(reference);
|
||||
}
|
||||
|
||||
public void remove_ref(Gitg.Ref reference)
|
||||
{
|
||||
d_refs_list.remove_ref(reference);
|
||||
}
|
||||
|
||||
public void replace_ref(Gitg.Ref old_ref, Gitg.Ref new_ref)
|
||||
{
|
||||
d_refs_list.replace_ref(old_ref, new_ref);
|
||||
}
|
||||
|
||||
public void set_busy(Gitg.Ref reference, bool busy)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void edit_ref_name(Gitg.Ref reference, owned GitgExt.RefNameEditingDone done)
|
||||
{
|
||||
d_refs_list.edit(reference, (owned)done);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ex: ts=4 noet
|
|
@ -38,6 +38,7 @@ namespace GitgHistory
|
|||
private Settings d_settings;
|
||||
|
||||
private Paned d_main;
|
||||
private Gitg.PopupMenu d_refs_list_popup;
|
||||
|
||||
private Gitg.UIElements<GitgExt.HistoryPanel> d_panels;
|
||||
|
||||
|
@ -310,10 +311,8 @@ namespace GitgHistory
|
|||
d_panels = new Gitg.UIElements<GitgExt.HistoryPanel>(extset,
|
||||
d_main.stack_panel);
|
||||
|
||||
d_main.refs_list.popup_menu.connect(on_refs_list_popup_menu);
|
||||
d_main.refs_list.button_press_event.connect(on_refs_list_button_press_event);
|
||||
|
||||
d_main.refs_list.editing_done.connect(on_ref_edited);
|
||||
d_refs_list_popup = new Gitg.PopupMenu(d_main.refs_list);
|
||||
d_refs_list_popup.populate_menu.connect(on_refs_list_populate_menu);
|
||||
|
||||
d_main.refs_list.notify["selection"].connect(() => {
|
||||
update_walker();
|
||||
|
@ -325,87 +324,6 @@ namespace GitgHistory
|
|||
BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
|
||||
private void on_ref_edited(Gitg.Ref reference, string new_text, bool cancelled)
|
||||
{
|
||||
if (cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string orig;
|
||||
string? prefix;
|
||||
|
||||
var pn = reference.parsed_name;
|
||||
|
||||
if (pn.rtype == Gitg.RefType.REMOTE)
|
||||
{
|
||||
orig = pn.remote_branch;
|
||||
prefix = pn.prefix + "/" + pn.remote_name + "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
orig = pn.shortname;
|
||||
prefix = pn.prefix;
|
||||
}
|
||||
|
||||
if (orig == new_text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Ggit.Ref.is_valid_name(@"$prefix$new_text"))
|
||||
{
|
||||
var msg = _("The specified name ‘%s’ contains invalid characters").printf(new_text);
|
||||
|
||||
application.show_infobar(_("Invalid name"),
|
||||
msg,
|
||||
Gtk.MessageType.ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var branch = reference as Ggit.Branch;
|
||||
Gitg.Ref? new_ref = null;
|
||||
|
||||
try
|
||||
{
|
||||
var repo = application.repository;
|
||||
var appenv = application.environment;
|
||||
var signature = repo.get_signature_with_environment(appenv);
|
||||
|
||||
if (branch != null)
|
||||
{
|
||||
var msg = _("rename: branch %s to %s").printf(branch.get_name(),
|
||||
new_text);
|
||||
|
||||
new_ref = branch.move(new_text,
|
||||
Ggit.CreateFlags.NONE,
|
||||
signature,
|
||||
msg) as Gitg.Ref;
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = _("rename: ref %s to %s").printf(reference.get_name(),
|
||||
new_text);
|
||||
|
||||
new_ref = reference.rename(new_text,
|
||||
false,
|
||||
signature,
|
||||
msg) as Gitg.Ref;
|
||||
}
|
||||
}
|
||||
catch (Error e)
|
||||
{
|
||||
application.show_infobar(_("Failed to rename"),
|
||||
e.message,
|
||||
Gtk.MessageType.ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
d_main.refs_list.replace_ref(reference, new_ref);
|
||||
}
|
||||
|
||||
private void add_ref_action(Gee.LinkedList<GitgExt.RefAction> actions, GitgExt.RefAction? action)
|
||||
{
|
||||
if (action.visible)
|
||||
|
@ -414,36 +332,33 @@ namespace GitgHistory
|
|||
}
|
||||
}
|
||||
|
||||
private bool refs_list_popup_menu(Gtk.Widget widget, Gdk.EventButton? event)
|
||||
private Gtk.Menu? on_refs_list_populate_menu(Gdk.EventButton? event)
|
||||
{
|
||||
var button = (event == null ? 0 : event.button);
|
||||
var time = (event == null ? Gtk.get_current_event_time() : event.time);
|
||||
if (event != null)
|
||||
{
|
||||
var row = d_main.refs_list.get_row_at_y((int)event.y);
|
||||
d_main.refs_list.select_row(row);
|
||||
}
|
||||
|
||||
var actions = new Gee.LinkedList<GitgExt.RefAction>();
|
||||
var references = d_main.refs_list.selection;
|
||||
|
||||
if (references.is_empty || references.first() != references.last())
|
||||
{
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
var reference = references.first();
|
||||
|
||||
var rename = new Gitg.RefActionRename(application.action_interface,
|
||||
reference);
|
||||
var af = new ActionInterface(application, d_main.refs_list);
|
||||
|
||||
rename.activated.connect(() => { on_rename_activated(rename); });
|
||||
|
||||
add_ref_action(actions, rename);
|
||||
|
||||
add_ref_action(actions,
|
||||
new Gitg.RefActionDelete(application.action_interface,
|
||||
reference));
|
||||
add_ref_action(actions, new Gitg.RefActionRename(af, reference));
|
||||
add_ref_action(actions, new Gitg.RefActionDelete(af, reference));
|
||||
|
||||
var exts = new Peas.ExtensionSet(Gitg.PluginsEngine.get_default(),
|
||||
typeof(GitgExt.RefAction),
|
||||
"action_interface",
|
||||
application.action_interface,
|
||||
af,
|
||||
"reference",
|
||||
reference);
|
||||
|
||||
|
@ -453,7 +368,7 @@ namespace GitgHistory
|
|||
|
||||
if (actions.is_empty)
|
||||
{
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
Gtk.Menu menu = new Gtk.Menu();
|
||||
|
@ -463,35 +378,9 @@ namespace GitgHistory
|
|||
ac.populate_menu(menu);
|
||||
}
|
||||
|
||||
menu.attach_to_widget(widget, null);
|
||||
menu.popup(null, null, null, button, time);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void on_rename_activated(Gitg.RefActionRename action)
|
||||
{
|
||||
d_main.refs_list.begin_editing(action.reference as Gitg.Ref);
|
||||
}
|
||||
|
||||
private bool on_refs_list_popup_menu(Gtk.Widget widget)
|
||||
{
|
||||
return refs_list_popup_menu(widget, null);
|
||||
}
|
||||
|
||||
private bool on_refs_list_button_press_event(Gtk.Widget widget, Gdk.EventButton event)
|
||||
{
|
||||
Gdk.Event *ev = (Gdk.Event *)(&event);
|
||||
|
||||
if (!ev->triggers_context_menu())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var row = d_main.refs_list.get_row_at_y((int)event.y);
|
||||
d_main.refs_list.select_row(row);
|
||||
|
||||
return refs_list_popup_menu(widget, event);
|
||||
// To keep actions alive as long as the menu is alive
|
||||
menu.set_data("gitg-ext-actions", actions);
|
||||
return menu;
|
||||
}
|
||||
|
||||
private void update_walker()
|
||||
|
|
|
@ -43,7 +43,7 @@ libgitg_ext_libgitg_ext_1_0_la_LIBADD = \
|
|||
|
||||
libgitg_ext_libgitg_ext_1_0_la_VALASOURCES = \
|
||||
libgitg-ext/gitg-ext-assembly-info.vala \
|
||||
libgitg-ext/gitg-ext-action-interface.vala \
|
||||
libgitg-ext/gitg-ext-ref-action-interface.vala \
|
||||
libgitg-ext/gitg-ext-action.vala \
|
||||
libgitg-ext/gitg-ext-commit-action.vala \
|
||||
libgitg-ext/gitg-ext-ref-action.vala \
|
||||
|
|
|
@ -22,8 +22,6 @@ namespace GitgExt
|
|||
|
||||
public interface Action : Object
|
||||
{
|
||||
public abstract ActionInterface action_interface { get; construct set; }
|
||||
|
||||
public abstract string label { get; }
|
||||
public abstract bool enabled { get; }
|
||||
public abstract bool visible { get; }
|
||||
|
|
|
@ -45,11 +45,6 @@ public interface Application : Object
|
|||
*/
|
||||
public abstract GitgExt.Activity? current_activity { owned get; }
|
||||
|
||||
/**
|
||||
* The application action interface.
|
||||
*/
|
||||
public abstract GitgExt.ActionInterface action_interface { owned get; }
|
||||
|
||||
/**
|
||||
* Set the current application main activity.
|
||||
*
|
||||
|
|
|
@ -20,8 +20,17 @@
|
|||
namespace GitgExt
|
||||
{
|
||||
|
||||
public interface ActionInterface : Object
|
||||
public delegate void RefNameEditingDone(string new_name, bool cancelled);
|
||||
|
||||
public interface RefActionInterface : Object
|
||||
{
|
||||
public abstract Application application { owned get; construct set; }
|
||||
|
||||
public abstract void add_ref(Gitg.Ref reference);
|
||||
public abstract void remove_ref(Gitg.Ref reference);
|
||||
public abstract void replace_ref(Gitg.Ref old_ref, Gitg.Ref new_ref);
|
||||
public abstract void set_busy(Gitg.Ref reference, bool busy);
|
||||
public abstract void edit_ref_name(Gitg.Ref reference, owned RefNameEditingDone callback);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,8 @@ namespace GitgExt
|
|||
|
||||
public interface RefAction : Action
|
||||
{
|
||||
public abstract Ggit.Ref reference { get; construct set; }
|
||||
public abstract RefActionInterface action_interface { get; construct set; }
|
||||
public abstract Gitg.Ref reference { get; construct set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue