Implement history navigation as ListBox

This commit is contained in:
Jesse van den Kieboom 2014-01-15 00:45:04 +01:00 committed by Jesse van den Kieboom
parent 7cfa45167b
commit d0aa7692d7
8 changed files with 497 additions and 628 deletions

View file

@ -64,7 +64,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-navigation.vala \
gitg/history/gitg-history-refs-list.vala \
gitg/history/gitg-history-paned.vala \
gitg/commit/gitg-commit.vala \
gitg/commit/gitg-commit-paned.vala \

View file

@ -1,581 +0,0 @@
/*
* 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 enum Hint
{
NONE,
HEADER,
DEFAULT,
SEPARATOR
}
private enum Column
{
ICON_NAME,
NAME,
TEXT,
HEADER,
HINT,
SECTION,
OID
}
public delegate void NavigationActivated(int numclick);
private class Activated : Object
{
private NavigationActivated d_activated;
public Activated(owned NavigationActivated? activated)
{
d_activated = (owned)activated;
}
public void activate(int numclick)
{
if (d_activated != null)
{
d_activated(numclick);
}
}
}
public class Navigation : Gtk.TreeStore
{
// Do this to pull in config.h before glib.h (for gettext...)
private const string version = Gitg.Config.VERSION;
private List<Gitg.Ref> d_all;
private uint d_oid;
private SList<Gtk.TreeIter?> d_parents;
private uint d_sections;
private Activated[] d_callbacks;
private bool d_reloading;
private Gitg.Repository? d_repository;
private string? d_selected_head;
private Gtk.TreeIter? d_selected_iter;
public signal void ref_activated(Gitg.Ref? r);
public Navigation(Gitg.Repository? repo)
{
Object(repository: repo);
}
construct
{
set_column_types({typeof(string),
typeof(string),
typeof(string),
typeof(string),
typeof(uint),
typeof(uint),
typeof(uint)
});
d_callbacks = new Activated[100];
d_callbacks.length = 0;
}
public List<Gitg.Ref> all
{
get { return d_all; }
}
[Notify]
public Gitg.Repository repository
{
get { return d_repository; }
set
{
d_repository = value;
reload();
}
}
public Gtk.TreeIter? selected_iter
{
get { return d_selected_iter; }
set { d_selected_iter = value; }
}
public bool show_expanders
{
get { return false; }
}
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);
}
private void populate(Gitg.Repository repo)
{
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_name((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;
});
if (repo.is_head_detached())
{
d_all.prepend(repo.get_head());
}
} catch {}
d_all.reverse();
begin_section();
append_normal(_("All commits"), null, null, (nc) => activate_ref(null));
// Branches
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";
isdef = true;
}
}
catch {}
if (isdef)
{
append_default(item.parsed_name.shortname,
item.parsed_name.name,
icon,
(nc) => activate_ref(item));
}
else
{
append_normal(item.parsed_name.shortname,
item.parsed_name.name,
icon,
(nc) => activate_ref(item));
}
}
end_header();
// Remotes
begin_header(_("Remotes"), null);
foreach (var rname in remotenames)
{
begin_header(rname, null);
var rrefs = remotes.lookup(rname);
rrefs.sort((CompareDataFunc)sort_remote_refs);
foreach (var rref in remotes.lookup(rname))
{
var it = rref;
append_normal(rref.parsed_name.remote_branch,
rref.parsed_name.name,
null,
(nc) => activate_ref(it));
}
end_header();
}
end_header();
// Tags
begin_header(_("Tags"), null);
foreach (var item in tags)
{
var it = item;
append_normal(item.parsed_name.shortname,
item.parsed_name.name,
null,
(nc) => activate_ref(it));
}
end_header();
end_section();
}
private new void append(string text,
string? name,
string? icon_name,
uint hint,
owned NavigationActivated? callback,
out Gtk.TreeIter iter)
{
if (d_parents != null)
{
base.append(out iter, d_parents.data);
}
else
{
base.append(out iter, null);
}
@set(iter,
Column.ICON_NAME, icon_name,
Column.NAME, name,
hint == Hint.HEADER ? Column.HEADER : Column.TEXT, text,
Column.HINT, hint,
Column.SECTION, d_sections,
Column.OID, d_oid);
if (d_selected_head == name && name != null ||
d_selected_head == "--ALL REFS--" && text == _("All commits"))
{
d_selected_iter = iter;
}
d_callbacks += new Activated((owned)callback);
++d_oid;
}
private Navigation append_normal(string text,
string? name,
string? icon_name,
owned NavigationActivated? callback)
{
Gtk.TreeIter iter;
append(text, name, icon_name, Hint.NONE, (owned)callback, out iter);
return this;
}
private Navigation append_default(string text,
string? name,
string? icon_name,
owned NavigationActivated? callback)
{
Gtk.TreeIter iter;
append(text, name, icon_name, Hint.DEFAULT, (owned)callback, out iter);
return this;
}
private Navigation begin_header(string text,
string? icon_name)
{
Gtk.TreeIter iter;
append(text, null, icon_name, Hint.HEADER, null, out iter);
d_parents.prepend(iter);
return this;
}
private Navigation end_header()
{
if (d_parents != null)
{
d_parents.remove_link(d_parents);
}
return this;
}
private uint begin_section()
{
d_parents = null;
return d_sections;
}
private void end_section()
{
++d_sections;
}
public new void clear()
{
base.clear();
d_oid = 0;
d_sections = 0;
d_callbacks.length = 0;
}
public void reload()
{
if (d_repository != null)
{
d_reloading = true;
clear();
populate(d_repository);
d_reloading = false;
}
}
public void activate(Gtk.TreeIter iter, int numclick)
{
uint oid;
@get(iter, Column.OID, out oid);
if (d_callbacks[oid] != null)
{
d_callbacks[oid].activate(numclick);
}
}
private void activate_ref(Gitg.Ref? r)
{
if (d_reloading)
{
return;
}
if (r != null)
{
d_selected_head = r.parsed_name.name;
}
else
{
d_selected_head = "--ALL REFS--";
}
ref_activated(r);
}
}
public class NavigationView : Gtk.TreeView
{
private void build_ui()
{
var col = new Gtk.TreeViewColumn();
var padcell = new Gtk.CellRendererText();
var iconcell = new Gtk.CellRendererPixbuf();
var headercell = new Gtk.CellRendererText();
var cell = new Gtk.CellRendererText();
iconcell.follow_state = true;
headercell.ellipsize = Pango.EllipsizeMode.MIDDLE;
cell.ellipsize = Pango.EllipsizeMode.MIDDLE;
padcell.xpad = 6;
headercell.ypad = 6;
headercell.weight = Pango.Weight.BOLD;
col.pack_start(padcell, false);
col.pack_start(iconcell, false);
col.pack_start(headercell, true);
col.pack_start(cell, true);
col.set_attributes(iconcell, "icon-name", Column.ICON_NAME);
col.set_attributes(headercell, "text", Column.HEADER);
col.set_attributes(cell, "text", Column.TEXT);
col.set_cell_data_func(iconcell, (layout, cell, model, iter) => {
string? icon_name;
model.get(iter, Column.ICON_NAME, out icon_name);
cell.visible = (icon_name != null);
});
col.set_cell_data_func(headercell, (layout, cell, model, iter) => {
Hint hint;
model.get(iter, Column.HINT, out hint);
cell.visible = (hint == Hint.HEADER);
});
col.set_cell_data_func(cell, (layout, cell, model, iter) => {
Hint hint;
model.get(iter, Column.HINT, out hint);
cell.visible = (hint != Hint.HEADER);
});
set_row_separator_func((model, iter) => {
Hint hint;
model.get(iter, Column.HINT, out hint);
return hint == Hint.SEPARATOR;
});
append_column(col);
get_selection().set_select_function((sel, model, path, cursel) => {
Gtk.TreeIter iter;
model.get_iter(out iter, path);
uint hint;
model.get(iter, Column.HINT, out hint);
return hint != Hint.HEADER;
});
get_selection().changed.connect((sel) => {
Gtk.TreeIter iter;
if (sel.get_selected(null, out iter))
{
model.activate(iter, 1);
}
});
set_show_expanders(model.show_expanders);
if (model.show_expanders)
{
set_level_indentation(0);
}
else
{
set_level_indentation(12);
}
}
public new Navigation model
{
get { return base.get_model() as Navigation; }
set { base.set_model(value); build_ui(); }
}
private bool select_first_in(Gtk.TreeIter? parent, bool seldef)
{
Gtk.TreeIter iter;
if (!model.iter_children(out iter, parent))
{
return false;
}
while (true)
{
uint hint;
model.get(iter, Column.HINT, out hint);
if (hint == Hint.HEADER)
{
if (select_first_in(iter, seldef))
{
return true;
}
}
if (!seldef || hint == Hint.DEFAULT)
{
get_selection().select_iter(iter);
return true;
}
if (!model.iter_next(ref iter))
{
return false;
}
}
}
public void select_first()
{
select_first_in(null, true) || select_first_in(null, false);
}
public void select()
{
if (model.selected_iter != null)
{
get_selection().select_iter(model.selected_iter);
model.selected_iter = null;
}
else
{
select_first();
}
}
protected override void row_activated(Gtk.TreePath path, Gtk.TreeViewColumn col)
{
Gtk.TreeIter iter;
model.get_iter(out iter, path);
model.activate(iter, 2);
}
}
}
// ex: ts=4 noet

View file

@ -33,7 +33,7 @@ class Paned : Gtk.Paned
private Gtk.StackSwitcher d_stack_switcher_panels;
[GtkChild]
private NavigationView d_navigation_view;
private RefsList d_refs_list;
[GtkChild]
private Gtk.TreeView d_commit_list_view;
@ -117,9 +117,9 @@ class Paned : Gtk.Paned
Object(orientation: Gtk.Orientation.HORIZONTAL);
}
public NavigationView navigation_view
public RefsList refs_list
{
get { return d_navigation_view; }
get { return d_refs_list; }
}
public Gtk.TreeView commit_list_view

View file

@ -0,0 +1,418 @@
/*
* 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
{
private int ref_type_sort_order(Gitg.RefType ref_type)
{
switch (ref_type)
{
case Gitg.RefType.NONE:
return 0;
case Gitg.RefType.BRANCH:
return 1;
case Gitg.RefType.REMOTE:
return 2;
case Gitg.RefType.TAG:
return 3;
}
return 4;
}
private interface RefTyped : Object
{
public abstract Gitg.RefType ref_type { get; }
}
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-history-ref-row.ui")]
private class RefRow : RefTyped, Gtk.Box
{
private const string version = Gitg.Config.VERSION;
[GtkChild]
private Gtk.Image d_icon;
[GtkChild]
private Gtk.Label d_label;
public Gitg.Ref? reference { get; set; }
public Gitg.RefType ref_type
{
get { return reference != null ? reference.parsed_name.rtype : Gitg.RefType.NONE; }
}
public RefRow(Gitg.Ref? reference)
{
Object(orientation: Gtk.Orientation.HORIZONTAL, spacing: 6);
this.reference = reference;
d_label.label = label_text();
if (is_head)
{
d_icon.icon_name = "object-select-symbolic";
d_icon.show();
}
if (reference != null)
{
margin_left += 12;
}
if (ref_type == Gitg.RefType.REMOTE)
{
margin_left += 12;
}
}
private string label_text()
{
if (reference == null)
{
return _("All commits");
}
var pn = reference.parsed_name;
if (pn.rtype == Gitg.RefType.REMOTE)
{
return pn.remote_branch;
}
return pn.shortname;
}
private bool is_head
{
get
{
if (reference == null)
{
return false;
}
var branch = reference as Ggit.Branch;
if (branch != null)
{
try
{
return branch.is_head();
} catch { return false; }
}
return false;
}
}
private int compare_type(RefRow other)
{
var pnme = reference.parsed_name;
var pnot = other.reference.parsed_name;
if (pnme.rtype != pnot.rtype)
{
var i1 = ref_type_sort_order(pnme.rtype);
var i2 = ref_type_sort_order(pnot.rtype);
return i1 < i2 ? -1 : (i1 > i2 ? 1 : 0);
}
if (pnme.rtype == Gitg.RefType.REMOTE)
{
return pnme.remote_name.casefold().collate(pnot.remote_name.casefold());
}
return 0;
}
public int compare_to(RefRow other)
{
if (reference == null)
{
return -1;
}
if (other.reference == null)
{
return 1;
}
var ct = compare_type(other);
if (ct != 0)
{
return ct;
}
var t1 = label_text();
var t2 = other.label_text();
var hassep1 = t1.index_of_char('/');
var hassep2 = t2.index_of_char('/');
if ((hassep1 >= 0) != (hassep2 >= 0))
{
return hassep1 >= 0 ? 1 : -1;
}
return t1.casefold().collate(t2.casefold());
}
}
private class RefHeader : RefTyped, Gtk.Label
{
private Gitg.RefType d_rtype;
private bool d_is_sub_header_remote;
private string d_name;
public Gitg.RefType ref_type
{
get { return d_rtype; }
}
public RefHeader(Gitg.RefType rtype, string name)
{
var escaped = Markup.escape_text(name);
set_markup(@"<b>$escaped</b>");
xalign = 0;
d_name = name;
d_rtype = rtype;
margin_top = 3;
margin_bottom = 3;
margin_left = 16;
}
public RefHeader.remote(string name)
{
this(Gitg.RefType.REMOTE, name);
d_is_sub_header_remote = true;
margin_left += 12;
}
public int compare_to(RefHeader other)
{
// Both are headers of remote type
if (d_is_sub_header_remote != other.d_is_sub_header_remote)
{
return d_is_sub_header_remote ? 1 : -1;
}
return d_name.casefold().collate(other.d_name.casefold());
}
}
public class RefsList : Gtk.ListBox
{
public signal void edited(Gitg.Ref reference, Gtk.TreePath path, string text);
public signal void ref_activated(Gitg.Ref? r);
private Gitg.Repository? d_repository;
private Gee.HashMap<string, RefHeader> d_remote_headers;
public Gitg.Repository? repository
{
get { return d_repository; }
set
{
if (d_repository != value)
{
d_repository = value;
}
refresh();
}
}
construct
{
d_remote_headers = new Gee.HashMap<string, RefHeader>();
set_sort_func(sort_rows);
}
private int sort_rows(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
{
var c1 = row1.get_child();
var c2 = row2.get_child();
var r1 = ((RefTyped)c1).ref_type;
var r2 = ((RefTyped)c2).ref_type;
// Compare types first
var rs1 = ref_type_sort_order(r1);
var rs2 = ref_type_sort_order(r2);
if (rs1 != rs2)
{
return rs1 < rs2 ? -1 : 1;
}
var head1 = c1 as RefHeader;
var ref1 = c1 as RefRow;
var head2 = c2 as RefHeader;
var ref2 = c2 as RefRow;
if ((head1 == null) != (head2 == null))
{
// Only one is a header
return head1 != null ? -1 : 1;
}
else if (head1 != null && head2 != null)
{
return head1.compare_to(head2);
}
else
{
return ref1.compare_to(ref2);
}
}
private void clear()
{
d_remote_headers = new Gee.HashMap<string, RefHeader>();
foreach (var child in get_children())
{
child.destroy();
}
}
private void add_header(Gitg.RefType ref_type, string name)
{
var header = new RefHeader(ref_type, name);
header.show();
add(header);
}
private RefHeader add_remote_header(string name)
{
var header = new RefHeader.remote(name);
header.show();
add(header);
return header;
}
private void add_ref(Gitg.Ref? reference)
{
var row = new RefRow(reference);
row.show();
add(row);
}
// Checks if the provided reference is a symbolic ref with the name HEAD.
private bool ref_is_a_symbolic_head(Gitg.Ref reference)
{
if (reference.get_reference_type() != Ggit.RefType.SYMBOLIC)
{
return false;
}
string name;
if (reference.parsed_name.rtype == Gitg.RefType.REMOTE)
{
name = reference.parsed_name.remote_branch;
}
else
{
name = reference.parsed_name.shortname;
}
return name == "HEAD";
}
public void refresh()
{
clear();
if (d_repository == null)
{
return;
}
add_ref(null);
add_header(Gitg.RefType.BRANCH, _("Branches"));
add_header(Gitg.RefType.REMOTE, _("Remotes"));
add_header(Gitg.RefType.TAG, _("Tags"));
try
{
d_repository.references_foreach_name((nm) => {
Gitg.Ref? r;
try
{
r = d_repository.lookup_reference(nm);
} catch { return 0; }
// Skip symbolic refs named HEAD since they aren't really
// useful to show (we get these for remotes for example)
if (ref_is_a_symbolic_head(r))
{
return 0;
}
if (r.parsed_name.rtype == Gitg.RefType.REMOTE)
{
var remote = r.parsed_name.remote_name;
if (!d_remote_headers.has_key(remote))
{
d_remote_headers[remote] = add_remote_header(remote);
}
}
add_ref(r);
return 0;
});
} catch {}
}
private RefRow? get_ref_row(Gtk.ListBoxRow row)
{
return row.get_child() as RefRow;
}
protected override void row_activated(Gtk.ListBoxRow row)
{
var r = get_ref_row(row);
if (r != null)
{
ref_activated(r.reference);
}
}
}
}
// ex: ts=4 noet

View file

@ -29,8 +29,8 @@ namespace GitgHistory
public GitgExt.Application? application { owned get; construct set; }
private Navigation? d_navigation_model;
private Gitg.CommitModel? d_commit_list_model;
private Gee.HashSet<Ggit.OId> d_selected;
private Ggit.OId? d_scroll_to;
private float d_scroll_y;
@ -102,11 +102,6 @@ namespace GitgHistory
d_selected = new Gee.HashSet<Ggit.OId>((Gee.HashDataFunc<Ggit.OId>)Ggit.OId.hash,
(Gee.EqualDataFunc<Ggit.OId>)Ggit.OId.equal);
d_navigation_model = new Navigation(application.repository);
d_navigation_model.ref_activated.connect((r) => {
on_ref_activated(d_navigation_model, r);
});
d_commit_list_model = new Gitg.CommitModel(application.repository);
d_commit_list_model.started.connect(on_commit_model_started);
d_commit_list_model.finished.connect(on_commit_model_finished);
@ -221,22 +216,11 @@ namespace GitgHistory
return -1;
}
private void on_ref_activated(Navigation n, Gitg.Ref? r)
{
update_walker(n, r);
}
public void activate()
{
d_main.navigation_view.expand_all();
d_main.navigation_view.select_first();
}
private void reload()
{
var view = d_main.commit_list_view;
double vadj = d_main.navigation_view.get_vadjustment().get_value();
double vadj = d_main.refs_list.get_adjustment().get_value();
d_selected.clear();
@ -290,28 +274,24 @@ namespace GitgHistory
d_commit_list_model.repository = repository;
// Reloads branches, tags, etc.
d_navigation_model.repository = repository;
d_main.refs_list.repository = repository;
ulong sid = 0;
sid = d_main.navigation_view.size_allocate.connect((a) => {
d_main.navigation_view.get_vadjustment().set_value(vadj);
sid = d_main.refs_list.size_allocate.connect((a) => {
d_main.refs_list.get_adjustment().set_value(vadj);
if (sid != 0)
{
d_main.navigation_view.disconnect(sid);
d_main.refs_list.disconnect(sid);
}
});
d_main.navigation_view.expand_all();
d_main.navigation_view.select();
}
private void build_ui()
{
d_main = new Paned();
d_main.navigation_view.model = d_navigation_model;
d_main.commit_list_view.model = d_commit_list_model;
d_main.commit_list_view.get_selection().changed.connect((sel) => {
@ -329,9 +309,18 @@ namespace GitgHistory
d_panels = new Gitg.UIElements<GitgExt.HistoryPanel>(extset,
d_main.stack_panel);
d_main.refs_list.ref_activated.connect((r) => {
update_walker(r);
});
application.bind_property("repository", d_main.refs_list,
"repository",
BindingFlags.DEFAULT |
BindingFlags.SYNC_CREATE);
}
private void update_walker(Navigation n, Gitg.Ref? head)
private void update_walker(Gitg.Ref? head)
{
Ggit.OId? id = null;
@ -358,25 +347,45 @@ namespace GitgHistory
else
{
var included = new Ggit.OId[] {};
var repo = application.repository;
// Simply push all the refs
foreach (Gitg.Ref r in n.all)
try
{
try
{
var resolved = r.resolve();
repo.references_foreach_name((nm) => {
Gitg.Ref? r;
try
{
var t = application.repository.lookup<Ggit.Tag>(resolved.get_target());
included += t.get_target_id();
}
catch
r = repo.lookup_reference(nm);
} catch { return 0; }
try
{
included += resolved.get_target();
}
} catch {}
}
var resolved = r.resolve();
try
{
var t = repo.lookup<Ggit.Tag>(resolved.get_target());
included += t.get_target_id();
}
catch
{
included += resolved.get_target();
}
} catch {}
return 0;
});
} catch {}
try
{
if (repo.is_head_detached())
{
var resolved = repo.get_head().resolve();
included += resolved.get_target();
}
} catch {}
d_commit_list_model.set_include(included);
}

View file

@ -11,6 +11,7 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-clone-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-author-details-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-history-paned.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-history-ref-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-paned.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-dialog.ui</file>
<file compressed="true">ui/style.css</file>

View file

@ -32,11 +32,9 @@
<class name="sidebar"/>
</style>
<child>
<object class="GitgHistoryNavigationView" id="d_navigation_view">
<object class="GitgHistoryRefsList" id="d_refs_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="name">tree_view_navigation</property>
</object>
</child>
</object>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.3 -->
<!-- interface-requires gitg 0.0 -->
<!-- interface-requires gd 1.0 -->
<template class="GitgHistoryRefRow">
<property name="orientation">horizontal</property>
<property name="visible">True</property>
<property name="margin_left">16</property>
<child>
<object class="GtkImage" id="d_icon">
<property name="icon_size">1</property>
</object>
</child>
<child>
<object class="GtkLabel" id="d_label">
<property name="visible">True</property>
<property name="ellipsize">middle</property>
<property name="xalign">0</property>
</object>
</child>
</template>
</interface>
<!-- vi:ts=2:et -->