[gitg] Added format patch action to revision context menu



commit bd90f99b52126abc80162f60e83f22b247af4d81
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Tue Jan 19 10:03:49 2010 +0100

    Added format patch action to revision context menu

 gitg/gitg-dnd.c      |   17 +------
 gitg/gitg-menus.xml  |    7 +++
 gitg/gitg-revision.c |   17 ++++++++
 gitg/gitg-revision.h |    2 +
 gitg/gitg-window.c   |  110 +++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 137 insertions(+), 16 deletions(-)
---
diff --git a/gitg/gitg-dnd.c b/gitg/gitg-dnd.c
index 9643416..e1af4e3 100644
--- a/gitg/gitg-dnd.c
+++ b/gitg/gitg-dnd.c
@@ -336,21 +336,10 @@ create_revision_drag_icon (GtkTreeView  *tree_view,
 static gchar *
 generate_format_patch_filename (GitgRevision *revision)
 {
-	gchar *subject = g_strdup (gitg_revision_get_subject (revision));
-	gchar *ptr = subject;
-	gchar *filename;
-
-	do
-	{
-		if (g_utf8_get_char (ptr) == ' ')
-		{
-			*ptr = '-';
-		}
-	} while (*(ptr = g_utf8_next_char (ptr)));
-	
-	filename = g_strdup_printf ("0001-%s.patch", subject);
-	g_free (subject);
+	gchar *name = gitg_revision_get_format_patch_name (revision);
+	gchar *filename = g_strdup_printf ("0001-%s.patch", name);
 
+	g_free (name);
 	return filename;
 }
 
diff --git a/gitg/gitg-menus.xml b/gitg/gitg-menus.xml
index d0b6f20..d479bf8 100644
--- a/gitg/gitg-menus.xml
+++ b/gitg/gitg-menus.xml
@@ -106,6 +106,12 @@
           </object>
         </child>
         <child>
+          <object class="GtkAction" id="FormatPatchAction">
+            <property name="label" translatable="yes">Format patch</property>
+            <signal name="activate" handler="on_revision_format_patch_activate"/>
+          </object>
+        </child>
+        <child>
           <object class="GtkAction" id="SquashAction">
             <property name="label">Squash revisions</property>
             <signal name="activate" handler="on_revision_squash_activate"/>
@@ -147,6 +153,7 @@
         <menu name="CherryPick" action="CherryPickAction">
           <placeholder name="Placeholder"/>
         </menu>
+        <menuitem action="FormatPatchAction"/>
         <menuitem action="SquashAction"/>
       </popup>
     </ui>
diff --git a/gitg/gitg-revision.c b/gitg/gitg-revision.c
index 62d001e..16ec192 100644
--- a/gitg/gitg-revision.c
+++ b/gitg/gitg-revision.c
@@ -290,3 +290,20 @@ gitg_revision_get_lane(GitgRevision *revision)
 {
 	return (GitgLane *)g_slist_nth_data(revision->lanes, revision->mylane);
 }
+
+gchar *
+gitg_revision_get_format_patch_name (GitgRevision *revision)
+{
+	gchar *ret = g_strdup (revision->subject);
+	gchar *ptr = ret;
+
+	do
+	{
+		if (g_utf8_get_char (ptr) == ' ')
+		{
+			*ptr = '-';
+		}
+	} while (*(ptr = g_utf8_next_char (ptr)));
+
+	return ret;
+}
diff --git a/gitg/gitg-revision.h b/gitg/gitg-revision.h
index 41fea32..8722a5d 100644
--- a/gitg/gitg-revision.h
+++ b/gitg/gitg-revision.h
@@ -66,6 +66,8 @@ char gitg_revision_get_sign(GitgRevision *revision);
 GitgRevision *gitg_revision_ref(GitgRevision *revision);
 void gitg_revision_unref(GitgRevision *revision);
 
+gchar *gitg_revision_get_format_patch_name (GitgRevision *revision);
+
 G_END_DECLS
 
 #endif /* __GITG_REVISION_H__ */
diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c
index d6ca152..3ee0cbf 100644
--- a/gitg/gitg-window.c
+++ b/gitg/gitg-window.c
@@ -2353,7 +2353,6 @@ popup_revision (GitgWindow *window, GdkEventButton *event)
 
 			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))
 		{
@@ -2361,7 +2360,6 @@ popup_revision (GitgWindow *window, GdkEventButton *event)
 
 			gtk_action_set_visible (squash, TRUE);
 			gtk_action_set_visible (tag, FALSE);
-			gtk_action_set_visible (cherry_pick, FALSE);
 		}
 	}
 
@@ -2522,7 +2520,115 @@ on_tag_dialog_response (GtkWidget *dialog, gint response, TagInfo *info)
 	}
 }
 
+typedef struct
+{
+	GitgWindow *window;
+	GList *revisions;
+} FormatPatchInfo;
+
+static void
+on_format_patch_response (GtkDialog       *dialog,
+                          gint             response,
+                          FormatPatchInfo *info)
+{
+	if (response == GTK_RESPONSE_ACCEPT)
+	{
+		if (!info->revisions->next)
+		{
+			gchar *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+			gitg_window_add_branch_action (info->window,
+			                               gitg_branch_actions_format_patch (info->window,
+			                                                                 info->revisions->data,
+			                                                                 uri));
+			g_free (uri);
+		}
+		else
+		{
+			/* TODO: implement once multiple selection is realized */
+		}
+	}
 
+	g_list_foreach (info->revisions, (GFunc)gitg_revision_unref, NULL);
+	g_list_free (info->revisions);
+
+	g_slice_free (FormatPatchInfo, info);
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+void
+on_revision_format_patch_activate (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);
+
+	GtkWidget *dialog;
+
+	if (!rows->next)
+	{
+		GtkTreeIter iter;
+		GitgRevision *revision;
+
+		gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
+		gtk_tree_model_get (model, &iter, 0, &revision, -1);
+
+		/* Single one, pick filename */
+		dialog = gtk_file_chooser_dialog_new (_("Save format patch"),
+		                                      GTK_WINDOW (window),
+		                                      GTK_FILE_CHOOSER_ACTION_SAVE,
+		                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		                                      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+		                                      NULL);
+
+		gchar *name = gitg_revision_get_format_patch_name (revision);
+		gchar *filename = g_strdup_printf ("0001-%s.patch", name);
+
+		gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
+		g_free (filename);
+		g_free (name);
+
+		gitg_revision_unref (revision);
+	}
+	else
+	{
+		/* TODO: Implement selecting folder once multiple selection is realized */
+	}
+
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
+	                                     gitg_repository_get_path (window->priv->repository));
+
+	FormatPatchInfo *info = g_slice_new (FormatPatchInfo);
+	info->window = window;
+	info->revisions = NULL;
+
+	GList *item;
+
+	for (item = rows; item; item = g_list_next (item))
+	{
+		GtkTreeIter iter;
+		GitgRevision *revision;
+
+		gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
+		gtk_tree_model_get (model, &iter, 0, &revision, -1);
+
+		info->revisions = g_list_prepend (info->revisions, revision);
+	}
+
+	info->revisions = g_list_reverse (info->revisions);
+
+	g_signal_connect (dialog,
+	                  "response",
+	                  G_CALLBACK (on_format_patch_response),
+	                  info);
+
+	gtk_widget_show (dialog);
+
+	g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
+	g_list_free (rows);
+}
 
 void
 on_revision_tag_activate (GtkAction *action, GitgWindow *window)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]