diff --git a/gitg/gitg-branch-actions.c b/gitg/gitg-branch-actions.c index 68f9a175..81e88883 100644 --- a/gitg/gitg-branch-actions.c +++ b/gitg/gitg-branch-actions.c @@ -1771,7 +1771,6 @@ gitg_branch_actions_cherry_pick (GitgWindow *window, NULL); g_free (message); - gitg_ref_free (head); g_free (sha1); return ret; diff --git a/gitg/gitg-menus.xml b/gitg/gitg-menus.xml index 6855c762..d0b6f202 100644 --- a/gitg/gitg-menus.xml +++ b/gitg/gitg-menus.xml @@ -100,10 +100,15 @@ + + + Cherry-pick on... + + - Squash revisions - + Squash revisions + @@ -138,8 +143,11 @@ - - + + + + + diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c index 9a92f50a..4926683d 100644 --- a/gitg/gitg-window.c +++ b/gitg/gitg-window.c @@ -97,6 +97,9 @@ struct _GitgWindowPrivate gboolean destroy_has_run; guint merge_rebase_uid; GtkActionGroup *merge_rebase_action_group; + + guint cherry_pick_uid; + GtkActionGroup *cherry_pick_action_group; GitgRef *popup_refs[2]; GList *branch_actions; @@ -1967,6 +1970,9 @@ update_merge_rebase (GitgWindow *window, GitgRef *ref) g_object_unref (rebaseac); g_object_unref (mergeac); + + g_free (rebase); + g_free (merge); } else { @@ -2207,6 +2213,125 @@ consecutive_revisions (GitgWindow *window, GList *rows) return FALSE; } +static void +on_cherry_pick_activated (GtkAction *action, GitgWindow *window) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + + selection = gtk_tree_view_get_selection (window->priv->tree_view); + GList *rows = gtk_tree_selection_get_selected_rows (selection, &model); + + if (!rows || rows->next) + { + return; + } + + GtkTreeIter iter; + GitgRevision *rev; + + gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data); + gtk_tree_model_get (model, &iter, 0, &rev, -1); + + GitgRef *ref = g_object_get_data (G_OBJECT (action), + DYNAMIC_ACTION_DATA_KEY); + + add_branch_action (window, gitg_branch_actions_cherry_pick (window, + rev, + ref)); + + gitg_revision_unref (rev); + + g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); + g_list_free (rows); +} + +static void +update_cherry_pick (GitgWindow *window) +{ + if (window->priv->cherry_pick_uid != 0) + { + gtk_ui_manager_remove_ui (window->priv->menus_ui_manager, + window->priv->cherry_pick_uid); + } + + GtkActionGroup *ac = window->priv->cherry_pick_action_group; + + if (ac) + { + GList *actions = gtk_action_group_list_actions (ac); + GList *item; + + for (item = actions; item; item = g_list_next (item)) + { + gtk_action_group_remove_action (ac, (GtkAction *)item->data); + } + + g_list_free (actions); + } + + if (window->priv->cherry_pick_uid == 0) + { + window->priv->cherry_pick_uid = gtk_ui_manager_new_merge_id (window->priv->menus_ui_manager); + } + + if (ac == NULL) + { + ac = gtk_action_group_new ("GitgCherryPickActions"); + + window->priv->cherry_pick_action_group = ac; + + gtk_ui_manager_insert_action_group (window->priv->menus_ui_manager, + ac, + 0); + } + + GSList *refs = gitg_repository_get_refs (window->priv->repository); + GSList *item; + + for (item = refs; item; item = g_slist_next (item)) + { + GitgRef *r = GITG_REF (item->data); + + if (gitg_ref_get_ref_type (r) == GITG_REF_TYPE_BRANCH) + { + gchar const *rname = gitg_ref_get_shortname (r); + gchar *acname = g_strconcat ("CherryPick", rname, "Action", NULL); + + GtkAction *action = gtk_action_new (acname, rname, NULL, NULL); + + g_object_set_data_full (G_OBJECT (action), + DYNAMIC_ACTION_DATA_KEY, + gitg_ref_copy (r), + (GDestroyNotify)gitg_ref_free); + + g_signal_connect (action, + "activate", + G_CALLBACK (on_cherry_pick_activated), + window); + + gtk_action_group_add_action (ac, action); + + gchar *name = g_strconcat ("CherryPick", rname, NULL); + + gtk_ui_manager_add_ui (window->priv->menus_ui_manager, + window->priv->cherry_pick_uid, + "/ui/revision_popup/CherryPick/Placeholder", + name, + acname, + GTK_UI_MANAGER_MENUITEM, + FALSE); + g_free (name); + + g_object_unref (action); + g_free (acname); + } + } + + g_slist_foreach (refs, (GFunc)gitg_ref_free, NULL); + g_slist_free (refs); +} + static gboolean popup_revision (GitgWindow *window, GdkEventButton *event) { @@ -2217,22 +2342,29 @@ popup_revision (GitgWindow *window, GdkEventButton *event) gboolean show = FALSE; + update_cherry_pick (window); + if (rows) { GtkAction *tag = gtk_ui_manager_get_action (window->priv->menus_ui_manager, "/ui/revision_popup/TagAction"); GtkAction *squash = gtk_ui_manager_get_action (window->priv->menus_ui_manager, "/ui/revision_popup/SquashAction"); + GtkAction *cherry_pick = gtk_ui_manager_get_action (window->priv->menus_ui_manager, "/ui/revision_popup/CherryPick"); if (!rows->next) { show = TRUE; + gtk_action_set_visible (squash, FALSE); gtk_action_set_visible (tag, TRUE); + gtk_action_set_visible (cherry_pick, TRUE); } else if (consecutive_revisions (window, rows)) { show = TRUE; + gtk_action_set_visible (squash, TRUE); gtk_action_set_visible (tag, FALSE); + gtk_action_set_visible (cherry_pick, FALSE); } }