Improved branch selection and added local branches selection

This commit is contained in:
Jesse van den Kieboom 2010-01-09 23:24:35 +01:00
parent 684f9172e9
commit 6120609ac0
3 changed files with 228 additions and 99 deletions

View file

@ -99,6 +99,8 @@ struct _GitgRepositoryPrivate
gint grow_size;
gchar **last_args;
gchar **selection;
guint idle_relane_id;
LoadStage load_stage;
@ -370,6 +372,7 @@ gitg_repository_finalize(GObject *object)
/* Free cached args */
g_strfreev(rp->priv->last_args);
g_strfreev(rp->priv->selection);
if (rp->priv->idle_relane_id)
{
@ -1023,6 +1026,22 @@ reload_revisions(GitgRepository *repository, GError **error)
return gitg_repository_run_commandv(repository, repository->priv->loader, error, "log", "--pretty=format:%H\x01%an\x01%s\x01%at", "--encoding=UTF-8", "-g", "refs/stash", NULL);
}
static gchar **
copy_strv (gchar const **ptr, gint argc)
{
GPtrArray *ret = g_ptr_array_new ();
gint i = 0;
while (ptr && ((argc >= 0 && i < argc) || (argc < 0 && ptr[i])))
{
g_ptr_array_add (ret, g_strdup (ptr[i]));
++i;
}
g_ptr_array_add (ret, NULL);
return (gchar **)g_ptr_array_free (ret, FALSE);
}
static void
build_log_args(GitgRepository *self, gint argc, gchar const **av)
{
@ -1066,6 +1085,9 @@ build_log_args(GitgRepository *self, gint argc, gchar const **av)
g_strfreev(self->priv->last_args);
self->priv->last_args = argv;
g_strfreev (self->priv->selection);
self->priv->selection = copy_strv (av, argc);
}
static gchar *
@ -1591,3 +1613,11 @@ gitg_repository_get_loaded (GitgRepository *repository)
return repository->priv->load_stage == LOAD_STAGE_LAST &&
!gitg_runner_running (repository->priv->loader);
}
gchar const **
gitg_repository_get_current_selection (GitgRepository *repository)
{
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
return (gchar const **)repository->priv->selection;
}

View file

@ -110,6 +110,7 @@ gchar *gitg_repository_parse_head(GitgRepository *repository);
void gitg_repository_reload(GitgRepository *repository);
gchar **gitg_repository_get_remotes (GitgRepository *repository);
gchar const **gitg_repository_get_current_selection (GitgRepository *repository);
G_END_DECLS

View file

@ -59,7 +59,8 @@ enum
{
COLUMN_BRANCHES_NAME,
COLUMN_BRANCHES_REF,
COLUMN_BRANCHES_ICON
COLUMN_BRANCHES_ICON,
COLUMN_BRANCHES_SELECTION
};
struct _GitgWindowPrivate
@ -402,42 +403,27 @@ on_branches_combo_changed(GtkComboBox *combo, GitgWindow *window)
gchar *name;
GtkTreeIter iter;
GtkTreeIter next;
gchar **selection;
gtk_combo_box_get_active_iter(combo, &iter);
next = iter;
if (!gtk_tree_model_iter_next(gtk_combo_box_get_model(combo), &next))
{
name = g_strdup("--all");
}
else
{
GitgRef *ref;
gtk_tree_model_get (gtk_combo_box_get_model(combo),
&iter,
COLUMN_BRANCHES_REF, &ref,
COLUMN_BRANCHES_SELECTION, &selection,
-1);
if (ref == NULL)
if (selection != NULL)
{
return;
gitg_repository_load (window->priv->repository, 1, (gchar const **)selection, NULL);
g_strfreev (selection);
}
name = g_strdup(gitg_ref_get_name(ref));
gitg_ref_free(ref);
}
gitg_repository_load(window->priv->repository, 1, (gchar const **)&name, NULL);
g_free(name);
}
static void
build_branches_combo(GitgWindow *window, GtkBuilder *builder)
{
GtkComboBox *combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "combo_box_branches"));
window->priv->branches_store = gtk_tree_store_new(3, G_TYPE_STRING, GITG_TYPE_REF, G_TYPE_STRING);
window->priv->branches_store = gtk_tree_store_new(4, G_TYPE_STRING, GITG_TYPE_REF, G_TYPE_STRING, G_TYPE_STRV);
window->priv->combo_branches = combo;
GtkTreeIter iter;
@ -446,6 +432,7 @@ build_branches_combo(GitgWindow *window, GtkBuilder *builder)
&iter,
COLUMN_BRANCHES_NAME, _("Select branch"),
COLUMN_BRANCHES_REF, NULL,
COLUMN_BRANCHES_SELECTION, NULL,
-1);
gtk_combo_box_set_model(combo, GTK_TREE_MODEL(window->priv->branches_store));
@ -1021,6 +1008,30 @@ clear_branches_combo(GitgWindow *window)
gtk_combo_box_set_active(window->priv->combo_branches, 0);
}
static gboolean
equal_selection (gchar const **s1,
gchar const **s2)
{
if (!s1 || !s2)
{
return s1 == s2;
}
gint i = 0;
while (s1[i] && s2[i])
{
if (strcmp (s1[i], s2[i]) != 0)
{
return FALSE;
}
++i;
}
return !s1[i] && !s2[i];
}
static void
fill_branches_combo(GitgWindow *window)
{
@ -1042,8 +1053,14 @@ fill_branches_combo(GitgWindow *window)
GtkTreeIter parent;
GitgRef *parentref = NULL;
GtkTreeStore *store = window->priv->branches_store;
GitgRef *current_ref = gitg_repository_get_current_ref (window->priv->repository);
gboolean refset = FALSE;
GitgRef *working_ref = gitg_repository_get_current_working_ref (window->priv->repository);
gchar const **current_selection = gitg_repository_get_current_selection (window->priv->repository);
GtkTreeRowReference *active_from_current_ref = NULL;
GtkTreeRowReference *active_from_selection = NULL;
for (item = refs; item; item = item->next)
{
@ -1055,11 +1072,13 @@ fill_branches_combo(GitgWindow *window)
if (gitg_ref_get_ref_type(ref) != prevtype)
{
/* Insert separator */
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store,
&iter,
COLUMN_BRANCHES_NAME, NULL,
COLUMN_BRANCHES_REF, NULL,
COLUMN_BRANCHES_SELECTION, NULL,
-1);
prevtype = gitg_ref_get_ref_type(ref);
@ -1071,6 +1090,7 @@ fill_branches_combo(GitgWindow *window)
{
parentref = ref;
/* Add parent item */
gtk_tree_store_append(store, &parent, NULL);
gtk_tree_store_set(store,
&parent,
@ -1080,6 +1100,7 @@ fill_branches_combo(GitgWindow *window)
if (gitg_ref_get_ref_type(ref) == GITG_REF_TYPE_REMOTE)
{
/* Add remote icon */
gtk_tree_store_set(store,
&parent,
COLUMN_BRANCHES_ICON, g_strdup(GTK_STOCK_NETWORK),
@ -1087,50 +1108,125 @@ fill_branches_combo(GitgWindow *window)
}
}
gtk_tree_store_append(window->priv->branches_store, &iter, &parent);
gtk_tree_store_append (store, &iter, &parent);
}
else
{
gtk_tree_store_append(window->priv->branches_store, &iter, NULL);
gtk_tree_store_append (store, &iter, NULL);
}
gtk_tree_store_set(window->priv->branches_store,
gchar const *selection[] = {
gitg_ref_get_name (ref),
NULL
};
gtk_tree_store_set (store,
&iter,
COLUMN_BRANCHES_NAME, gitg_ref_get_shortname(ref),
COLUMN_BRANCHES_REF, ref,
COLUMN_BRANCHES_SELECTION, selection,
-1);
if (!refset && gitg_ref_equal(current_ref, ref))
if (!active_from_current_ref && gitg_ref_equal (current_ref, ref))
{
gtk_combo_box_set_active_iter(window->priv->combo_branches, &iter);
refset = TRUE;
GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
&iter);
active_from_current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
path);
gtk_tree_path_free (path);
}
if (!active_from_selection &&
(current_selection && equal_selection (selection, current_selection)) ||
(!current_selection && gitg_ref_equal (ref, working_ref)))
{
GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
&iter);
active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
path);
gtk_tree_path_free (path);
}
}
/* Separator */
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store,
&iter,
COLUMN_BRANCHES_NAME, NULL,
COLUMN_BRANCHES_REF, NULL, -1);
COLUMN_BRANCHES_REF, NULL,
COLUMN_BRANCHES_SELECTION, NULL,
-1);
gchar const *selection[] = {
"--branches",
NULL
};
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store,
&iter,
COLUMN_BRANCHES_NAME, _("Local branches"),
COLUMN_BRANCHES_REF, NULL,
COLUMN_BRANCHES_SELECTION, selection,
-1);
if (!active_from_selection &&
current_selection && equal_selection (selection, current_selection))
{
GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
&iter);
active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
path);
gtk_tree_path_free (path);
}
selection[0] = "--all";
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store,
&iter,
COLUMN_BRANCHES_NAME, _("All branches"),
COLUMN_BRANCHES_REF, NULL,
COLUMN_BRANCHES_SELECTION, selection,
-1);
if (current_ref == NULL)
if (!active_from_selection &&
current_selection && equal_selection (selection, current_selection))
{
gtk_combo_box_set_active_iter (window->priv->combo_branches, &iter);
GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
&iter);
active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
path);
gtk_tree_path_free (path);
}
else if (!refset)
if (active_from_selection != NULL || active_from_current_ref != NULL)
{
gtk_combo_box_set_active(window->priv->combo_branches, 0);
GtkTreePath *path;
GtkTreeIter active;
path = gtk_tree_row_reference_get_path (active_from_selection ? active_from_selection : active_from_current_ref);
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &active, path);
gtk_combo_box_set_active_iter (window->priv->combo_branches, &active);
}
g_slist_foreach(refs, (GFunc)gitg_ref_free, NULL);
g_slist_free(refs);
if (active_from_selection)
{
gtk_tree_row_reference_free (active_from_selection);
}
if (active_from_current_ref)
{
gtk_tree_row_reference_free (active_from_current_ref);
}
}
static void
@ -1173,8 +1269,10 @@ on_repository_load(GitgRepository *repository, GitgWindow *window)
g_timer_start(window->priv->load_timer);
g_signal_handlers_block_by_func(window->priv->combo_branches, on_branches_combo_changed, window);
clear_branches_combo(window);
fill_branches_combo(window);
g_signal_handlers_unblock_by_func(window->priv->combo_branches, on_branches_combo_changed, window);
update_window_title (window);