gitg/plugins/history/gitg-history-navigation.vala
2013-03-30 21:24:21 +01:00

216 lines
4.7 KiB
Vala

/*
* This file is part of gitg
*
* Copyright (C) 2012 - 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
{
private class Navigation : Object, GitgExt.Navigation
{
// Do this to pull in config.h before glib.h (for gettext...)
private const string version = Gitg.Config.VERSION;
public GitgExt.Application? application { owned get; construct set; }
private List<Gitg.Ref> d_all;
public signal void ref_activated(Gitg.Ref? r);
public Navigation(GitgExt.Application app)
{
Object(application: app);
}
private static int sort_refs(Gitg.Ref a, Gitg.Ref b)
{
return a.parsed_name.shortname.ascii_casecmp(b.parsed_name.shortname);
}
private static int sort_remote_refs(Gitg.Ref a, Gitg.Ref b)
{
return a.parsed_name.remote_branch.ascii_casecmp(b.parsed_name.remote_branch);
}
public void populate(GitgExt.NavigationTreeModel model)
{
var repo = application.repository;
List<Gitg.Ref> branches = new List<Gitg.Ref>();
List<Gitg.Ref> tags = new List<Gitg.Ref>();
HashTable<string, Gee.LinkedList<Gitg.Ref>> remotes;
List<string> remotenames = new List<string>();
remotes = new HashTable<string, Gee.LinkedList<Gitg.Ref>>(str_hash, str_equal);
d_all = new List<Gitg.Ref>();
try
{
repo.references_foreach(Ggit.RefType.LISTALL, (nm) => {
Gitg.Ref? r;
try
{
r = repo.lookup_reference(nm);
} catch { return 0; }
d_all.prepend(r);
if (r.parsed_name.rtype == Gitg.RefType.BRANCH)
{
branches.insert_sorted(r, sort_refs);
}
else if (r.parsed_name.rtype == Gitg.RefType.TAG)
{
tags.insert_sorted(r, sort_refs);
}
else if (r.parsed_name.rtype == Gitg.RefType.REMOTE)
{
Gee.LinkedList<Gitg.Ref> lst;
string rname = r.parsed_name.remote_name;
if (!remotes.lookup_extended(rname, null, out lst))
{
Gee.LinkedList<Gitg.Ref> nlst = new Gee.LinkedList<Gitg.Ref>();
nlst.insert(0, r);
remotes.insert(rname, nlst);
remotenames.insert_sorted(rname, (a, b) => a.ascii_casecmp(b));
}
else
{
lst.insert(0, r);
}
}
return 0;
});
} catch {}
d_all.reverse();
if (CommandLine.all)
{
model.append_default(_("All commits"), null, (nc) => ref_activated(null));
}
else
{
model.append(_("All commits"), null, (nc) => ref_activated(null));
}
// Branches
model.begin_header(_("Branches"), null);
foreach (var item in branches)
{
var branch = item as Ggit.Branch;
string? icon = null;
bool isdef = false;
try
{
if (branch.is_head())
{
icon = "object-select-symbolic";
if (!CommandLine.all)
{
isdef = true;
}
}
}
catch {}
if (isdef)
{
model.append_default(item.parsed_name.shortname,
icon,
(nc) => ref_activated(item));
}
else
{
model.append(item.parsed_name.shortname,
icon,
(nc) => ref_activated(item));
}
}
model.end_header();
// Remotes
model.begin_header(_("Remotes"), null);
foreach (var rname in remotenames)
{
model.begin_header(rname, null);
var rrefs = remotes.lookup(rname);
rrefs.sort((CompareFunc)sort_remote_refs);
foreach (var rref in remotes.lookup(rname))
{
var it = rref;
model.append(rref.parsed_name.remote_branch,
null,
(nc) => ref_activated(it));
}
model.end_header();
}
model.end_header();
// Tags
model.begin_header(_("Tags"), null);
foreach (var item in tags)
{
var it = item;
model.append(item.parsed_name.shortname,
null,
(nc) => ref_activated(it));
}
model.end_header();
}
public List<Gitg.Ref> all
{
get { return d_all; }
}
public GitgExt.NavigationSide navigation_side
{
get { return GitgExt.NavigationSide.LEFT; }
}
public bool available
{
get { return true; }
}
public bool show_expanders
{
get { return false; }
}
}
}
// ex: ts=4 noet