gitg/plugins/history/gitg-history.vala

284 lines
6.3 KiB
Vala
Raw Normal View History

/*
* 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/>.
*/
2012-04-14 11:46:39 +00:00
namespace GitgHistory
{
/* The main history view. This view shows the equivalent of git log, but
* in a nice way with lanes, merges, ref labels etc.
*/
public class View : Object, GitgExt.UIElement, GitgExt.View, GitgExt.ObjectSelection
2012-04-14 11:46:39 +00:00
{
// 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; }
2012-04-14 11:46:39 +00:00
2012-04-15 12:58:01 +00:00
private Gtk.TreeView d_view;
private GitgGtk.CommitModel? d_model;
2012-07-18 07:35:53 +00:00
private Gee.HashSet<Ggit.OId> d_selected;
private ulong d_insertsig;
private Settings d_settings;
2012-04-15 12:58:01 +00:00
2012-04-14 11:46:39 +00:00
private Gtk.Widget d_main;
public string id
{
owned get { return "/org/gnome/gitg/Views/History"; }
}
public void foreach_selected(GitgExt.ForeachObjectSelectionFunc func)
{
bool breakit = false;
d_view.get_selection().selected_foreach((model, path, iter) => {
if (!breakit)
{
breakit = !func(d_model.commit_from_iter(iter));
}
});
}
2012-04-15 12:58:01 +00:00
construct
{
d_model = new GitgGtk.CommitModel(application.repository);
2012-07-18 07:35:53 +00:00
d_selected = new Gee.HashSet<Ggit.OId>(Ggit.OId.hash, (EqualFunc<Ggit.OId>)Ggit.OId.equal);
d_model.started.connect(on_commit_model_started);
d_model.finished.connect(on_commit_model_finished);
d_settings = new Settings("org.gnome.gitg.history.preferences");
d_settings.changed["topological-order"].connect((s, k) => {
update_sort_mode();
});
update_sort_mode();
2012-04-15 12:58:01 +00:00
application.bind_property("repository", d_model, "repository", BindingFlags.DEFAULT);
application.notify["repository"].connect((a, r) => {
notify_property("available");
});
2012-04-15 12:58:01 +00:00
}
private void update_sort_mode()
{
if (d_settings.get_boolean("topological-order"))
{
d_model.sort_mode |= Ggit.SortMode.TOPOLOGICAL;
}
else
{
d_model.sort_mode &= ~Ggit.SortMode.TOPOLOGICAL;
}
}
2012-07-18 07:35:53 +00:00
private void on_commit_model_started(Gitg.CommitModel model)
{
2012-07-18 08:08:54 +00:00
if (d_insertsig == 0)
2012-07-18 07:35:53 +00:00
{
d_insertsig = d_model.row_inserted.connect(on_row_inserted_select);
}
}
private void on_row_inserted_select(Gtk.TreeModel model, Gtk.TreePath path, Gtk.TreeIter iter)
{
var commit = d_model.commit_from_path(path);
2012-07-18 08:08:54 +00:00
if (d_selected.size == 0 || d_selected.remove(commit.get_id()))
2012-07-18 07:35:53 +00:00
{
d_view.get_selection().select_path(path);
2012-07-18 08:08:54 +00:00
}
2012-07-18 07:35:53 +00:00
2012-07-18 08:08:54 +00:00
if (d_selected.size == 0)
{
d_model.disconnect(d_insertsig);
d_insertsig = 0;
2012-07-18 07:35:53 +00:00
}
}
private void on_commit_model_finished(Gitg.CommitModel model)
{
if (d_insertsig != 0)
{
d_model.disconnect(d_insertsig);
d_insertsig = 0;
}
}
public bool available
2012-04-14 11:46:39 +00:00
{
get
{
// The history view is available only when there is a repository
return application.repository != null;
}
2012-04-14 11:46:39 +00:00
}
public string display_name
{
owned get { return _("History"); }
2012-04-14 11:46:39 +00:00
}
public string? icon
2012-04-14 11:46:39 +00:00
{
owned get { return "view-list-symbolic"; }
2012-04-14 11:46:39 +00:00
}
public Gtk.Widget? widget
{
owned get
{
if (d_main == null)
{
build_ui();
}
return d_main;
}
}
public GitgExt.Navigation? navigation
{
owned get
{
// Create the sidebar navigation for the history. This navigation
// will show branches, remotes and tags which can be used to
// filter the history
2012-04-14 11:46:39 +00:00
var ret = new Navigation(application);
2012-07-18 08:08:54 +00:00
ret.ref_activated.connect((r) => on_ref_activated(ret, r));
2012-04-14 11:46:39 +00:00
return ret;
}
}
public bool is_default_for(string action)
2012-04-14 11:46:39 +00:00
{
return application.repository != null && (action == "" || action == "history");
2012-04-14 11:46:39 +00:00
}
2012-07-18 08:08:54 +00:00
private void on_ref_activated(Navigation n, Gitg.Ref? r)
{
2012-07-18 08:08:54 +00:00
update_walker(n, r);
}
2012-04-14 11:46:39 +00:00
private void build_ui()
{
var ret = GitgExt.UI.from_builder("history/view-history.ui",
"scrolled_window_commit_list",
"commit_list_view");
2012-04-14 11:46:39 +00:00
2012-04-15 12:58:01 +00:00
d_view = ret["commit_list_view"] as Gtk.TreeView;
d_view.model = d_model;
d_view.get_selection().changed.connect((sel) => {
selection_changed();
});
d_main = ret["scrolled_window_commit_list"] as Gtk.Widget;
2012-04-14 11:46:39 +00:00
}
2012-07-18 08:08:54 +00:00
private void update_walker(Navigation n, Gitg.Ref? head)
2012-04-15 12:58:01 +00:00
{
Ggit.OId? id = null;
2012-04-15 12:58:01 +00:00
2012-07-17 11:56:09 +00:00
if (head != null)
2012-04-15 12:58:01 +00:00
{
2013-02-13 11:47:41 +00:00
id = head.get_target();
2012-07-17 11:56:09 +00:00
if (head.parsed_name.rtype == Gitg.RefType.TAG)
2012-04-15 12:58:01 +00:00
{
2012-07-17 11:56:09 +00:00
// See to resolve to the commit
try
{
2012-07-17 13:16:37 +00:00
var t = application.repository.lookup(id, typeof(Ggit.Tag)) as Ggit.Tag;
2012-07-17 11:56:09 +00:00
id = t.get_target_id();
} catch {}
}
}
2012-07-18 08:08:54 +00:00
d_selected.clear();
2012-04-15 12:58:01 +00:00
if (id != null)
2012-04-15 12:58:01 +00:00
{
2012-07-18 07:35:53 +00:00
d_selected.add(id);
d_model.set_include(new Ggit.OId[] { id });
2012-04-15 12:58:01 +00:00
}
2012-07-18 08:08:54 +00:00
else
{
var included = new Ggit.OId[] {};
// Simply push all the refs
foreach (Gitg.Ref r in n.all)
{
try
{
var resolved = r.resolve();
try
{
2013-02-13 11:47:41 +00:00
var t = application.repository.lookup(resolved.get_target(), typeof(Ggit.Tag)) as Ggit.Tag;
2012-07-18 08:08:54 +00:00
included += t.get_target_id();
}
catch
{
2013-02-13 11:47:41 +00:00
included += resolved.get_target();
2012-07-18 08:08:54 +00:00
}
} catch {}
}
d_model.set_include(included);
}
2012-04-15 12:58:01 +00:00
d_model.reload();
}
public bool enabled
{
get
{
return true;
}
}
public int negotiate_order(GitgExt.UIElement other)
{
return -1;
}
2012-04-14 11:46:39 +00:00
}
}
[ModuleInit]
public void peas_register_types(TypeModule module)
{
Peas.ObjectModule mod = module as Peas.ObjectModule;
mod.register_extension_type(typeof(GitgExt.View),
typeof(GitgHistory.View));
mod.register_extension_type(typeof(GitgExt.CommandLine),
typeof(GitgHistory.CommandLine));
2012-07-18 15:36:24 +00:00
mod.register_extension_type(typeof(GitgExt.Preferences),
typeof(GitgHistory.Preferences));
2012-04-14 11:46:39 +00:00
}
// ex: ts=4 noet