[Xfce4-commits] <thunar-vcs-plugin:master> Added support for git branch creation and switching
Peter de Ridder
noreply at xfce.org
Sun Feb 27 20:38:12 CET 2011
Updating branch refs/heads/master
to eed6c8ec0d339083cc24391403ee371e5ed3d906 (commit)
from f18b89b5bbfa042d121f1e787e7c46532ef81072 (commit)
commit eed6c8ec0d339083cc24391403ee371e5ed3d906
Author: Peter de Ridder <peter at xfce.org>
Date: Sun Feb 27 15:28:13 2011 +0100
Added support for git branch creation and switching
tvp-git-helper/tgh-branch-dialog.c | 151 ++++++++++++++++++++++++++++++-----
tvp-git-helper/tgh-branch.c | 119 +++++++++++++++++++++++++++-
2 files changed, 243 insertions(+), 27 deletions(-)
diff --git a/tvp-git-helper/tgh-branch-dialog.c b/tvp-git-helper/tgh-branch-dialog.c
index c4262a6..8c08f19 100644
--- a/tvp-git-helper/tgh-branch-dialog.c
+++ b/tvp-git-helper/tgh-branch-dialog.c
@@ -25,10 +25,12 @@
#include <gtk/gtk.h>
#include "tgh-common.h"
+#include "tgh-dialog-common.h"
#include "tgh-branch-dialog.h"
static void cancel_clicked (GtkButton*, gpointer);
-static void refresh_clicked (GtkButton*, gpointer);
+static void checkout_clicked (GtkButton*, gpointer);
+static void create_clicked (GtkButton*, gpointer);
struct _TghBranchDialog
{
@@ -37,7 +39,8 @@ struct _TghBranchDialog
GtkWidget *tree_view;
GtkWidget *close;
GtkWidget *cancel;
- GtkWidget *refresh;
+ GtkWidget *checkout;
+ GtkWidget *create;
};
struct _TghBranchDialogClass
@@ -49,7 +52,8 @@ G_DEFINE_TYPE (TghBranchDialog, tgh_branch_dialog, GTK_TYPE_DIALOG)
enum {
SIGNAL_CANCEL = 0,
- SIGNAL_REFRESH,
+ SIGNAL_CHECKOUT,
+ SIGNAL_CREATE,
SIGNAL_COUNT
};
@@ -64,12 +68,20 @@ tgh_branch_dialog_class_init (TghBranchDialogClass *klass)
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- signals[SIGNAL_REFRESH] = g_signal_new("refresh-clicked",
+
+ signals[SIGNAL_CHECKOUT] = g_signal_new("checkout-clicked",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[SIGNAL_CREATE] = g_signal_new("create-clicked",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
enum {
@@ -86,6 +98,7 @@ tgh_branch_dialog_init (TghBranchDialog *dialog)
GtkWidget *scroll_window;
GtkCellRenderer *renderer;
GtkTreeModel *model;
+ GtkWidget *box;
scroll_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
@@ -101,7 +114,7 @@ tgh_branch_dialog_init (TghBranchDialog *dialog)
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
- -1, _("Path"),
+ -1, _("Name"),
renderer, "text",
COLUMN_BRANCH, NULL);
@@ -116,23 +129,31 @@ tgh_branch_dialog_init (TghBranchDialog *dialog)
gtk_widget_show (tree_view);
gtk_widget_show (scroll_window);
- gtk_window_set_title (GTK_WINDOW (dialog), _("Branch"));
+ tgh_dialog_replace_action_area (GTK_DIALOG (dialog));
+ box = GTK_DIALOG (dialog)->action_area;
- gtk_button_box_set_layout(GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), GTK_BUTTONBOX_EDGE);
+ dialog->checkout = button = gtk_button_new_from_stock(GTK_STOCK_JUMP_TO);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (checkout_clicked), dialog);
+ gtk_widget_show (button);
- dialog->cancel = button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, FALSE, TRUE, 0);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cancel_clicked), dialog);
+ dialog->create = button = gtk_button_new_from_stock(GTK_STOCK_NEW);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (create_clicked), dialog);
gtk_widget_show (button);
- dialog->refresh = button = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, FALSE, TRUE, 0);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (refresh_clicked), dialog);
- gtk_widget_hide (button);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Branch"));
dialog->close = button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+ gtk_widget_hide (button);
+
+ dialog->cancel = button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cancel_clicked), dialog);
gtk_widget_show (button);
+ tgh_make_homogeneous (dialog->checkout, dialog->create, dialog->close, dialog->cancel, NULL);
+
gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
}
@@ -182,7 +203,7 @@ tgh_branch_dialog_done (TghBranchDialog *dialog)
g_return_if_fail (TGH_IS_BRANCH_DIALOG (dialog));
gtk_widget_hide (dialog->cancel);
- gtk_widget_show (dialog->refresh);
+ gtk_widget_show (dialog->close);
}
static void
@@ -191,23 +212,109 @@ cancel_clicked (GtkButton *button, gpointer user_data)
TghBranchDialog *dialog = TGH_BRANCH_DIALOG (user_data);
gtk_widget_hide (dialog->cancel);
- gtk_widget_show (dialog->refresh);
+ gtk_widget_show (dialog->close);
g_signal_emit (dialog, signals[SIGNAL_CANCEL], 0);
}
static void
-refresh_clicked (GtkButton *button, gpointer user_data)
+checkout_clicked (GtkButton *button, gpointer user_data)
{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
GtkTreeModel *model;
+ gchar *name;
+
TghBranchDialog *dialog = TGH_BRANCH_DIALOG (user_data);
- gtk_widget_hide (dialog->refresh);
- gtk_widget_show (dialog->cancel);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->tree_view));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter, COLUMN_BRANCH, &name, -1);
+
+ gtk_widget_hide (dialog->close);
+ gtk_widget_show (dialog->cancel);
- g_signal_emit (dialog, signals[SIGNAL_REFRESH], 0);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_CHECKOUT], 0, name);
+
+ g_free (name);
+ }
+}
+
+static void
+create_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeModel *model;
+ GtkWidget *name_dialog;
+ GtkWidget *label, *image, *hbox, *vbox, *name_entry;
+ gchar *name;
+ gint result;
+
+ TghBranchDialog *dialog = TGH_BRANCH_DIALOG (user_data);
+
+ name_dialog = gtk_dialog_new_with_buttons (NULL, GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
+ gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1);
+ gtk_window_set_resizable (GTK_WINDOW (name_dialog), FALSE);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (name_dialog), TRUE);
+
+ label = gtk_label_new (_("Branch name:"));
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+
+ name_entry = gtk_entry_new ();
+
+ hbox = gtk_hbox_new (FALSE, 12);
+ vbox = gtk_vbox_new (FALSE, 12);
+
+ gtk_box_pack_start (GTK_BOX (vbox), label,
+ FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox), name_entry,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), image,
+ FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), vbox,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (name_dialog))),
+ hbox,
+ FALSE, FALSE, 0);
+
+ gtk_container_set_border_width (GTK_CONTAINER (name_dialog), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (name_dialog)->vbox), 14); /* 14 + 2 * 5 = 24 */
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (name_dialog))), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (name_dialog))), 6);
+
+ gtk_widget_show_all (hbox);
+
+ result = gtk_dialog_run (GTK_DIALOG (name_dialog));
+ if (result != GTK_RESPONSE_ACCEPT)
+ {
+ gtk_widget_destroy (name_dialog);
+ return;
+ }
+
+ name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name_entry)));
+
+ gtk_widget_destroy (name_dialog);
+
+ gtk_widget_hide (dialog->close);
+ gtk_widget_show (dialog->cancel);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_CREATE], 0, name);
+
+ g_free (name);
}
diff --git a/tvp-git-helper/tgh-branch.c b/tvp-git-helper/tgh-branch.c
index 42469af..f646c27 100644
--- a/tvp-git-helper/tgh-branch.c
+++ b/tvp-git-helper/tgh-branch.c
@@ -37,7 +37,27 @@
#include "tgh-branch.h"
-static gchar *argv[] = {"git", "--no-pager", "branch", NULL};
+struct exit_args
+{
+ TghOutputParser *parser;
+ TghBranchDialog *dialog;
+};
+
+static gboolean branch_spawn (TghBranchDialog *dialog, GPid *pid);
+
+static void child_exit (GPid pid, gint status, gpointer user_data)
+{
+ struct exit_args *args = user_data;
+
+ tgh_child_exit (pid, status, args->parser);
+
+ if (branch_spawn (args->dialog, &pid))
+ tgh_replace_child (TRUE, pid);
+ else
+ tgh_branch_dialog_done (args->dialog);
+
+ g_free (args);
+}
static gboolean branch_spawn (TghBranchDialog *dialog, GPid *pid)
{
@@ -48,7 +68,9 @@ static gboolean branch_spawn (TghBranchDialog *dialog, GPid *pid)
GIOChannel *chan_err;
TghOutputParser *parser;
- if(!g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, &fd_out, &fd_err, &error))
+ static const gchar *argv[] = {"git", "--no-pager", "branch", NULL};
+
+ if(!g_spawn_async_with_pipes(NULL, (gchar**)argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, &fd_out, &fd_err, &error))
{
return FALSE;
}
@@ -65,10 +87,96 @@ static gboolean branch_spawn (TghBranchDialog *dialog, GPid *pid)
return TRUE;
}
-static void create_branch_child(TghBranchDialog *dialog, gpointer user_data)
+static gboolean branch_checkout_spawn (TghBranchDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ const gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (const gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "--no-pager";
+ argv[2] = "checkout";
+ argv[3] = "-q";
+ argv[4] = name;
+ argv[5] = NULL;
+
+ if(!g_spawn_async_with_pipes(NULL, (gchar**)argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, NULL, &fd_err, &error))
+ {
+ g_free (argv);
+ return FALSE;
+ }
+ g_free (argv);
+
+ parser = tgh_error_parser_new(GTK_WIDGET(dialog));
+
+ args = g_new (struct exit_args, 1);
+ args->parser = parser;
+ args->dialog = dialog;
+
+ g_child_watch_add(*pid, (GChildWatchFunc)child_exit, args);
+
+ chan_err = g_io_channel_unix_new(fd_err);
+ g_io_add_watch(chan_err, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, parser);
+
+ return TRUE;
+}
+
+static gboolean branch_create_spawn (TghBranchDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ const gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (const gchar*, 5);
+
+ argv[0] = "git";
+ argv[1] = "--no-pager";
+ argv[2] = "branch";
+ argv[3] = name;
+ argv[4] = NULL;
+
+ if(!g_spawn_async_with_pipes(NULL, (gchar**)argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, NULL, &fd_err, &error))
+ {
+ g_free (argv);
+ return FALSE;
+ }
+ g_free (argv);
+
+ parser = tgh_error_parser_new(GTK_WIDGET(dialog));
+
+ args = g_new (struct exit_args, 1);
+ args->parser = parser;
+ args->dialog = dialog;
+
+ g_child_watch_add(*pid, (GChildWatchFunc)child_exit, args);
+
+ chan_err = g_io_channel_unix_new(fd_err);
+ g_io_add_watch(chan_err, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, parser);
+
+ return TRUE;
+}
+
+static void checkout_branch(TghBranchDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (branch_checkout_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_branch_dialog_done(dialog);
+}
+
+static void create_branch(TghBranchDialog *dialog, const gchar *name, gpointer user_data)
{
GPid pid;
- if (branch_spawn(dialog, &pid))
+ if (branch_create_spawn(dialog, name, &pid))
tgh_replace_child(TRUE, pid);
else
tgh_branch_dialog_done(dialog);
@@ -86,7 +194,8 @@ gboolean tgh_branch (gchar **files, GPid *pid)
g_signal_connect(dialog, "cancel-clicked", tgh_cancel, NULL);
tgh_dialog_start (GTK_DIALOG (dialog), TRUE);
- g_signal_connect(dialog, "refresh-clicked", G_CALLBACK(create_branch_child), NULL);
+ g_signal_connect(dialog, "checkout-clicked", G_CALLBACK (checkout_branch), NULL);
+ g_signal_connect(dialog, "create-clicked", G_CALLBACK (create_branch), NULL);
return branch_spawn(TGH_BRANCH_DIALOG(dialog), pid);
}
More information about the Xfce4-commits
mailing list