gitg/libgitg/gitg-diff-view-commit-details.vala
2015-11-08 20:54:48 +01:00

299 lines
6.1 KiB
Vala

/*
* This file is part of gitg
*
* Copyright (C) 2015 - 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/>.
*/
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-diff-view-commit-details.ui")]
class Gitg.DiffViewCommitDetails : Gtk.Grid
{
[GtkChild( name = "image_avatar" )]
private Gtk.Image d_image_avatar;
[GtkChild( name = "label_author" )]
private Gtk.Label d_label_author;
[GtkChild( name = "label_author_date" )]
private Gtk.Label d_label_author_date;
[GtkChild( name = "label_committer" )]
private Gtk.Label d_label_committer;
[GtkChild( name = "label_committer_date" )]
private Gtk.Label d_label_committer_date;
[GtkChild( name = "label_subject" )]
private Gtk.Label d_label_subject;
[GtkChild( name = "label_sha1" )]
private Gtk.Label d_label_sha1;
[GtkChild( name = "grid_parents_container" )]
private Gtk.Grid d_grid_parents_container;
[GtkChild( name = "grid_parents" )]
private Gtk.Grid d_grid_parents;
[GtkChild( name = "expander_files" )]
private Gtk.Expander d_expander_files;
public bool expanded
{
get { return d_expander_files.expanded; }
set
{
if (d_expander_files.expanded != value)
{
d_expander_files.expanded = value;
}
}
}
public bool expander_visible
{
get { return d_expander_files.visible; }
set { d_expander_files.visible = value; }
}
private Cancellable? d_avatar_cancel;
private Ggit.Commit? d_commit;
public Ggit.Commit? commit
{
get { return d_commit; }
construct set
{
if (d_commit != value)
{
d_commit = value;
update();
}
}
}
private Ggit.Commit d_parent_commit;
public Ggit.Commit parent_commit
{
get { return d_parent_commit; }
set
{
if (d_parent_commit != value)
{
d_parent_commit = value;
var button = d_parents_map[value.get_id()];
if (button != null)
{
button.active = true;
}
}
}
}
public DiffViewCommitDetails(Ggit.Commit? commit)
{
Object(commit: commit);
}
private bool d_use_gravatar;
public bool use_gravatar
{
get { return d_use_gravatar; }
construct set
{
d_use_gravatar = value;
update_avatar();
}
default = true;
}
private Gee.HashMap<Ggit.OId, Gtk.RadioButton> d_parents_map;
construct
{
d_expander_files.notify["expanded"].connect(() => {
if (d_expander_files.expanded)
{
d_expander_files.label = _("Collapse all");
}
else
{
d_expander_files.label = _("Expand all");
}
notify_property("expanded");
});
}
protected override void dispose()
{
if (d_avatar_cancel != null)
{
d_avatar_cancel.cancel();
}
base.dispose();
}
private string author_to_markup(Ggit.Signature author)
{
var name = Markup.escape_text(author.get_name());
var email = Markup.escape_text(author.get_email());
return "%s &lt;<a href=\"mailto:%s\">%s</a>&gt;".printf(name, email, email);
}
private void update()
{
d_parents_map = new Gee.HashMap<Ggit.OId, Gtk.RadioButton>((oid) => oid.hash(), (o1, o2) => o1.equal(o2));
foreach (var child in d_grid_parents.get_children())
{
child.destroy();
}
if (commit == null)
{
return;
}
d_label_subject.label = commit.get_subject();
d_label_sha1.label = commit.get_id().to_string();
var author = commit.get_author();
d_label_author.label = author_to_markup(author);
d_label_author_date.label = author.get_time().to_timezone(author.get_time_zone()).format("%x %X %z");
var committer = commit.get_committer();
if (committer.get_name() != author.get_name() ||
committer.get_email() != author.get_email() ||
committer.get_time().compare(author.get_time()) != 0)
{
d_label_committer.label = _("Committed by %s").printf(author_to_markup(committer));
d_label_committer_date.label = committer.get_time().to_timezone(committer.get_time_zone()).format("%x %X %z");
d_label_committer.show();
d_label_committer_date.show();
}
else
{
d_label_committer.hide();
d_label_committer_date.hide();
}
var parents = commit.get_parents();
var first_parent = parents.size == 0 ? null : parents.get(0);
parent_commit = first_parent;
if (parents.size > 1)
{
d_grid_parents_container.show();
var grp = new SList<Gtk.RadioButton>();
Gtk.RadioButton? first = null;
foreach (var parent in parents)
{
var pid = parent.get_id().to_string().substring(0, 6);
var psubj = parent.get_subject();
var button = new Gtk.RadioButton.with_label(grp, @"$pid: $psubj");
if (first == null)
{
first = button;
}
button.group = first;
d_parents_map[parent.get_id()] = button;
button.show();
d_grid_parents.add(button);
var par = parent;
button.toggled.connect(() => {
if (button.active) {
parent_commit = par;
}
});
}
}
else
{
d_grid_parents_container.hide();
}
update_avatar();
}
private void update_avatar()
{
if (commit == null)
{
return;
}
if (d_use_gravatar)
{
if (d_avatar_cancel != null)
{
d_avatar_cancel.cancel();
}
d_avatar_cancel = new Cancellable();
var cancel = d_avatar_cancel;
var cache = AvatarCache.default();
cache.load.begin(commit.get_author().get_email(), d_image_avatar.pixel_size, cancel, (obj, res) => {
if (!cancel.is_cancelled())
{
var pixbuf = cache.load.end(res);
if (pixbuf != null)
{
d_image_avatar.pixbuf = pixbuf;
}
else
{
d_image_avatar.icon_name = "avatar-default-symbolic";
}
}
if (cancel == d_avatar_cancel)
{
d_avatar_cancel = null;
}
});
}
else
{
d_image_avatar.icon_name = "avatar-default-symbolic";
}
}
}
// ex:ts=4 noet