[Xfce4-commits] <thunar-vcs-plugin:thunarx-2> * thunar-vcs-plugin/tvp-git-action.c tvp-git-helper/main.c tvp-git-helper/tgh-common.[ch] tvp-git-helper/tgh-stash{, -dialog}.[ch]: Added stash action.
Peter de Ridder
noreply at xfce.org
Sun Nov 29 19:04:28 CET 2009
Updating branch refs/heads/thunarx-2
to 8f4ba0b888e20c4045f1d252c531c093e8a7b690 (commit)
from 3aa180a79c07d4855f6c779ac951d047dc164b10 (commit)
commit 8f4ba0b888e20c4045f1d252c531c093e8a7b690
Author: Peter de Ridder <peter at xfce.org>
Date: Sun Oct 25 00:45:40 2009 +0200
* thunar-vcs-plugin/tvp-git-action.c tvp-git-helper/main.c
tvp-git-helper/tgh-common.[ch]
tvp-git-helper/tgh-stash{,-dialog}.[ch]: Added stash action.
thunar-vcs-plugin/tvp-git-action.c | 2 +
tvp-git-helper/Makefile.am | 4 +
tvp-git-helper/main.c | 17 +
tvp-git-helper/tgh-common.c | 78 ++++
tvp-git-helper/tgh-common.h | 13 +-
tvp-git-helper/tgh-stash-dialog.c | 618 +++++++++++++++++++++++++++++
tvp-git-helper/tgh-stash-dialog.h | 55 +++
tvp-git-helper/tgh-stash.c | 377 ++++++++++++++++++
tvp-git-helper/{tgh-log.h => tgh-stash.h} | 8 +-
9 files changed, 1163 insertions(+), 9 deletions(-)
diff --git a/thunar-vcs-plugin/tvp-git-action.c b/thunar-vcs-plugin/tvp-git-action.c
index 792e545..c0d6022 100644
--- a/thunar-vcs-plugin/tvp-git-action.c
+++ b/thunar-vcs-plugin/tvp-git-action.c
@@ -265,6 +265,8 @@ tvp_git_action_create_menu_item (GtkAction *action)
add_subaction_u(GTK_MENU_SHELL(menu), "tvp::remove", Q_("Menu|Remove"), _("Remove"), GTK_STOCK_DELETE, _("Remove"));
add_subaction_u(GTK_MENU_SHELL(menu), "tvp::show", Q_("Menu|Show"), _("Show"), NULL, _("Show"));
if(tvp_action->property.is_parent)
+ add_subaction (action, GTK_MENU_SHELL(menu), "tvp::stash", Q_("Menu|Stash"), _("Stash"), GTK_STOCK_SAVE, "--stash");
+ if(tvp_action->property.is_parent)
add_subaction (action, GTK_MENU_SHELL(menu), "tvp::status", Q_("Menu|Status"), _("Status"), GTK_STOCK_DIALOG_INFO, "--status");
add_subaction_u(GTK_MENU_SHELL(menu), "tvp::tag", Q_("Menu|Tag"), _("Tag"), NULL, _("Tag"));
diff --git a/tvp-git-helper/Makefile.am b/tvp-git-helper/Makefile.am
index b3b56a9..ada3794 100644
--- a/tvp-git-helper/Makefile.am
+++ b/tvp-git-helper/Makefile.am
@@ -26,6 +26,8 @@ tvp_git_helper_SOURCES = \
tgh-log.c \
tgh-reset.h \
tgh-reset.c \
+ tgh-stash.h \
+ tgh-stash.c \
tgh-status.h \
tgh-status.c \
tgh-dialog-common.h \
@@ -38,6 +40,8 @@ tvp_git_helper_SOURCES = \
tgh-log-dialog.c \
tgh-notify-dialog.h \
tgh-notify-dialog.c \
+ tgh-stash-dialog.h \
+ tgh-stash-dialog.c \
tgh-status-dialog.h \
tgh-status-dialog.c \
tgh-transfer-dialog.h \
diff --git a/tvp-git-helper/main.c b/tvp-git-helper/main.c
index 6824ded..3313699 100644
--- a/tvp-git-helper/main.c
+++ b/tvp-git-helper/main.c
@@ -35,6 +35,7 @@
#include "tgh-clone.h"
#include "tgh-log.h"
#include "tgh-reset.h"
+#include "tgh-stash.h"
#include "tgh-status.h"
static GPid pid;
@@ -58,6 +59,7 @@ int main (int argc, char *argv[])
gboolean clone = FALSE;
gboolean log = FALSE;
gboolean reset = FALSE;
+ gboolean stash = FALSE;
gboolean status = FALSE;
gchar **files = NULL;
GError *error = NULL;
@@ -102,6 +104,12 @@ int main (int argc, char *argv[])
{ NULL, '\0', 0, 0, NULL, NULL, NULL }
};
+ GOptionEntry stash_options_table[] =
+ {
+ { "stash", '\0', 0, G_OPTION_ARG_NONE, &stash, N_("Execute stash action"), NULL },
+ { NULL, '\0', 0, 0, NULL, NULL, NULL }
+ };
+
GOptionEntry status_options_table[] =
{
{ "status", '\0', 0, G_OPTION_ARG_NONE, &status, N_("Execute status action"), NULL },
@@ -136,6 +144,10 @@ int main (int argc, char *argv[])
g_option_group_add_entries(option_group, reset_options_table);
g_option_context_add_group(option_context, option_group);
+ option_group = g_option_group_new("stash", N_("Stash Related Options:"), N_("Stash"), NULL, NULL);
+ g_option_group_add_entries(option_group, stash_options_table);
+ g_option_context_add_group(option_context, option_group);
+
option_group = g_option_group_new("status", N_("Status Related Options:"), N_("Status"), NULL, NULL);
g_option_group_add_entries(option_group, status_options_table);
g_option_context_add_group(option_context, option_group);
@@ -177,6 +189,11 @@ int main (int argc, char *argv[])
has_child = tgh_reset(files, &pid);
}
+ if(stash)
+ {
+ has_child = tgh_stash(files, &pid);
+ }
+
if(status)
{
has_child = tgh_status(files, &pid);
diff --git a/tvp-git-helper/tgh-common.c b/tvp-git-helper/tgh-common.c
index f4fc10d..a7b7d1d 100644
--- a/tvp-git-helper/tgh-common.c
+++ b/tvp-git-helper/tgh-common.c
@@ -40,6 +40,7 @@
#include "tgh-status-dialog.h"
#include "tgh-log-dialog.h"
#include "tgh-branch-dialog.h"
+#include "tgh-stash-dialog.h"
#include "tgh-common.h"
@@ -352,6 +353,83 @@ tgh_branch_parser_new (GtkWidget *dialog)
return TGH_OUTPUT_PARSER(parser);
}
+typedef struct {
+ TghOutputParser parent;
+ GtkWidget *dialog;
+} TghStashListParser;
+
+static void
+stash_list_parser_func (TghStashListParser *parser, gchar *line)
+{
+ TghStashDialog *dialog = TGH_STASH_DIALOG (parser->dialog);
+ if (line)
+ {
+ gchar *stash, *branch, *desc;
+ branch = strchr (line, ':');
+ *branch++ = '\0';
+ stash = g_strstrip (line);
+ desc = strchr (branch, ':');
+ *desc++ = '\0';
+ branch = g_strstrip (branch);
+ desc = g_strstrip (desc);
+ tgh_stash_dialog_add (dialog, stash, branch, desc);
+ }
+ else
+ {
+ tgh_stash_dialog_done (dialog);
+ g_free (parser);
+ }
+}
+
+TghOutputParser*
+tgh_stash_list_parser_new (GtkWidget *dialog)
+{
+ TghStashListParser *parser = g_new (TghStashListParser,1);
+
+ TGH_OUTPUT_PARSER (parser)->parse = TGH_OUTPUT_PARSER_FUNC (stash_list_parser_func);
+
+ parser->dialog = dialog;
+
+ return TGH_OUTPUT_PARSER (parser);
+}
+
+typedef struct {
+ TghOutputParser parent;
+ GtkWidget *dialog;
+} TghStashShowParser;
+
+static void
+stash_show_parser_func (TghStashShowParser *parser, gchar *line)
+{
+ TghStashDialog *dialog = TGH_STASH_DIALOG (parser->dialog);
+ if (line)
+ {
+ gchar *ptr, *file;
+ guint insertions = strtoul (line, &ptr, 10);
+ guint deletions = strtoul (ptr, &file, 10);
+ file++;
+ file = g_strndup (file, strlen(file)-1);
+ tgh_stash_dialog_add_file (dialog, insertions, deletions, file);
+ }
+ else
+ {
+ tgh_stash_dialog_done (dialog);
+ g_free (parser);
+ }
+}
+
+TghOutputParser*
+tgh_stash_show_parser_new (GtkWidget *dialog)
+{
+ TghStashShowParser *parser = g_new (TghStashShowParser,1);
+
+ TGH_OUTPUT_PARSER (parser)->parse = TGH_OUTPUT_PARSER_FUNC (stash_show_parser_func);
+
+ parser->dialog = dialog;
+
+ return TGH_OUTPUT_PARSER (parser);
+}
+
gboolean
tgh_parse_output_func(GIOChannel *source, GIOCondition condition, gpointer data)
{
diff --git a/tvp-git-helper/tgh-common.h b/tvp-git-helper/tgh-common.h
index 72d7522..ecdd6b2 100644
--- a/tvp-git-helper/tgh-common.h
+++ b/tvp-git-helper/tgh-common.h
@@ -34,15 +34,18 @@ struct _TghOutputParser {
TghOutputParserFunc parse;
};
-TghOutputParser* tgh_error_parser_new (GtkWidget *);
+TghOutputParser* tgh_error_parser_new (GtkWidget *);
-TghOutputParser* tgh_notify_parser_new (GtkWidget *);
+TghOutputParser* tgh_notify_parser_new (GtkWidget *);
-TghOutputParser* tgh_status_parser_new (GtkWidget *);
+TghOutputParser* tgh_status_parser_new (GtkWidget *);
-TghOutputParser* tgh_log_parser_new (GtkWidget *);
+TghOutputParser* tgh_log_parser_new (GtkWidget *);
-TghOutputParser* tgh_branch_parser_new (GtkWidget *);
+TghOutputParser* tgh_branch_parser_new (GtkWidget *);
+
+TghOutputParser* tgh_stash_list_parser_new (GtkWidget *);
+TghOutputParser* tgh_stash_show_parser_new (GtkWidget *);
gboolean tgh_parse_output_func (GIOChannel *, GIOCondition, gpointer);
diff --git a/tvp-git-helper/tgh-stash-dialog.c b/tvp-git-helper/tgh-stash-dialog.c
new file mode 100644
index 0000000..d51a804
--- /dev/null
+++ b/tvp-git-helper/tgh-stash-dialog.c
@@ -0,0 +1,618 @@
+/*-
+ * Copyright (c) 2006 Peter de Ridder <peter at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <thunar-vfs/thunar-vfs.h>
+#include <gtk/gtk.h>
+
+#include "tgh-common.h"
+#include "tgh-stash-dialog.h"
+
+static void selection_changed (GtkTreeView*, gpointer);
+static void cancel_clicked (GtkButton*, gpointer);
+static void save_clicked (GtkButton*, gpointer);
+static void apply_clicked (GtkButton*, gpointer);
+static void pop_clicked (GtkButton*, gpointer);
+static void drop_clicked (GtkButton*, gpointer);
+static void clear_clicked (GtkButton*, gpointer);
+static void tgh_make_homogeneous (GtkWidget *, ...) G_GNUC_NULL_TERMINATED;
+
+struct _TghStashDialog
+{
+ GtkDialog dialog;
+
+ GtkWidget *tree_view;
+ GtkWidget *file_view;
+ GtkWidget *save;
+ GtkWidget *apply;
+ GtkWidget *pop;
+ GtkWidget *drop;
+ GtkWidget *close;
+ GtkWidget *clear;
+ GtkWidget *cancel;
+};
+
+struct _TghStashDialogClass
+{
+ GtkDialogClass dialog_class;
+};
+
+G_DEFINE_TYPE (TghStashDialog, tgh_stash_dialog, GTK_TYPE_DIALOG)
+
+enum {
+ SIGNAL_CANCEL = 0,
+ SIGNAL_SAVE,
+ SIGNAL_APPLY,
+ SIGNAL_POP,
+ SIGNAL_DROP,
+ SIGNAL_CLEAR,
+ SIGNAL_SHOW,
+ SIGNAL_COUNT
+};
+
+static guint signals[SIGNAL_COUNT];
+
+static void
+tgh_stash_dialog_class_init (TghStashDialogClass *klass)
+{
+ signals[SIGNAL_CANCEL] = g_signal_new("cancel-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);
+
+ signals[SIGNAL_SAVE] = g_signal_new("save-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);
+
+ signals[SIGNAL_APPLY] = g_signal_new("apply-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);
+
+ signals[SIGNAL_POP] = g_signal_new("pop-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);
+
+ signals[SIGNAL_DROP] = g_signal_new("drop-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);
+
+ signals[SIGNAL_CLEAR] = g_signal_new("clear-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);
+
+ signals[SIGNAL_SHOW] = g_signal_new("selection-changed",
+ 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 {
+ COLUMN_NAME = 0,
+ COLUMN_BRANCH,
+ COLUMN_DESCRIPTION,
+ COLUMN_COUNT
+};
+
+enum {
+ FILE_COLUMN_FILE = 0,
+ FILE_COLUMN_PERCENTAGE,
+ FILE_COLUMN_CHANGES,
+ FILE_COLUMN_COUNT
+};
+
+static void
+tgh_stash_dialog_init (TghStashDialog *dialog)
+{
+ GtkWidget *button;
+ GtkWidget *tree_view;
+ GtkWidget *file_view;
+ GtkWidget *scroll_window;
+ GtkWidget *vpane;
+ GtkWidget *box;
+ GtkCellRenderer *renderer;
+ GtkTreeModel *model;
+
+ vpane = gtk_vpaned_new ();
+
+ scroll_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ dialog->tree_view = tree_view = gtk_tree_view_new ();
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+ -1, _("Name"), renderer,
+ "text", COLUMN_NAME,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+ -1, _("Branch"), renderer,
+ "text", COLUMN_BRANCH,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+ -1, _("Description"), renderer,
+ "text", COLUMN_DESCRIPTION,
+ NULL);
+
+ model = GTK_TREE_MODEL (gtk_list_store_new (COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
+
+ g_object_unref (model);
+
+ g_signal_connect (G_OBJECT (tree_view), "cursor-changed", G_CALLBACK (selection_changed), dialog);
+
+ gtk_container_add (GTK_CONTAINER (scroll_window), tree_view);
+ gtk_paned_pack1 (GTK_PANED(vpane), scroll_window, TRUE, FALSE);
+ gtk_widget_show (tree_view);
+ gtk_widget_show (scroll_window);
+
+ scroll_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+ dialog->file_view = file_view = gtk_tree_view_new ();
+
+ renderer = gtk_cell_renderer_progress_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (file_view),
+ -1, _("Changes"), renderer,
+ "value", FILE_COLUMN_PERCENTAGE,
+ "text", FILE_COLUMN_CHANGES,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (file_view),
+ -1, _("File"),
+ renderer, "text",
+ FILE_COLUMN_FILE, NULL);
+
+ model = GTK_TREE_MODEL (gtk_list_store_new (FILE_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING));
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (file_view), model);
+
+ g_object_unref (model);
+
+ gtk_container_add (GTK_CONTAINER (scroll_window), file_view);
+ gtk_paned_pack2 (GTK_PANED(vpane), scroll_window, TRUE, FALSE);
+ gtk_widget_show (file_view);
+ gtk_widget_show (scroll_window);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vpane, TRUE, TRUE, 0);
+ gtk_widget_show (vpane);
+
+ //gtk_button_box_set_layout(GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), GTK_BUTTONBOX_EDGE);
+ gtk_container_remove (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), GTK_DIALOG (dialog)->action_area);
+
+ GTK_DIALOG (dialog)->action_area = box = gtk_hbox_new (FALSE, 0);
+
+ gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), box,
+ FALSE, TRUE, 0);
+ gtk_widget_show (box);
+
+ gtk_box_reorder_child (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, 0);
+
+ //box = gtk_hbox_new (FALSE, 12);
+
+ dialog->save = button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (save_clicked), dialog);
+ gtk_widget_show (button);
+
+ dialog->apply = button = gtk_button_new_from_stock(GTK_STOCK_APPLY);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (apply_clicked), dialog);
+ gtk_widget_show (button);
+
+ dialog->pop = button = gtk_button_new_from_stock(GTK_STOCK_OK);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (pop_clicked), dialog);
+ gtk_widget_show (button);
+
+ dialog->drop = button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (drop_clicked), dialog);
+ gtk_widget_show (button);
+
+ dialog->clear = button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (clear_clicked), dialog);
+ gtk_widget_show (button);
+
+ //gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), box, FALSE, TRUE, 0);
+ //gtk_widget_show (box);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Stash"));
+
+ 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 (GTK_DIALOG (dialog)->action_area), button, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cancel_clicked), dialog);
+ gtk_widget_show (button);
+
+ tgh_make_homogeneous (dialog->save, dialog->apply, dialog->pop, dialog->drop, dialog->close, dialog->cancel, NULL);
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
+}
+
+GtkWidget*
+tgh_stash_dialog_new (const gchar *title, GtkWindow *parent, GtkDialogFlags flags)
+{
+ TghStashDialog *dialog = g_object_new (TGH_TYPE_STASH_DIALOG, NULL);
+
+ if(title)
+ gtk_window_set_title (GTK_WINDOW(dialog), title);
+
+ if(parent)
+ gtk_window_set_transient_for (GTK_WINDOW(dialog), parent);
+
+ if(flags & GTK_DIALOG_MODAL)
+ gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
+
+ if(flags & GTK_DIALOG_DESTROY_WITH_PARENT)
+ gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
+
+ if(flags & GTK_DIALOG_NO_SEPARATOR)
+ gtk_dialog_set_has_separator (GTK_DIALOG(dialog), FALSE);
+
+ return GTK_WIDGET(dialog);
+}
+
+static void
+tgh_make_homogeneous (GtkWidget *first, ...)
+{
+ GtkWidget *iter;
+ GtkRequisition request;
+ gint max_width = 0;
+ gint max_height = 0;
+ va_list ap;
+
+ va_start (ap, first);
+ iter = first;
+ while (iter)
+ {
+ gtk_widget_size_request(iter, &request);
+ if (request.width > max_width)
+ max_width = request.width;
+ if (request.height > max_height)
+ max_height = request.height;
+ iter = va_arg (ap, GtkWidget *);
+ }
+ va_end (ap);
+
+ va_start (ap, first);
+ iter = first;
+ while (iter)
+ {
+ gtk_widget_set_size_request (iter, max_width, max_height);
+ iter = va_arg (ap, GtkWidget *);
+ }
+ va_end (ap);
+}
+
+void
+tgh_stash_dialog_add (TghStashDialog *dialog, const gchar *name, const gchar *branch, const gchar *description)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (TGH_IS_STASH_DIALOG (dialog));
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COLUMN_NAME, name,
+ COLUMN_BRANCH, branch,
+ COLUMN_DESCRIPTION, description,
+ -1);
+}
+
+void
+tgh_stash_dialog_add_file (TghStashDialog *dialog, guint insertions, guint deletions, const gchar *file)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *changes;
+ guint sum;
+
+ g_return_if_fail (TGH_IS_STASH_DIALOG (dialog));
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+
+ changes = g_strdup_printf ("+%u -%u", insertions, deletions);
+ sum = insertions + deletions;
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ FILE_COLUMN_FILE, file,
+ FILE_COLUMN_PERCENTAGE, sum?insertions * 100 / sum:0,
+ FILE_COLUMN_CHANGES, changes,
+ -1);
+ g_free (changes);
+}
+
+void
+tgh_stash_dialog_done (TghStashDialog *dialog)
+{
+ g_return_if_fail (TGH_IS_STASH_DIALOG (dialog));
+
+ gtk_widget_hide (dialog->cancel);
+ gtk_widget_show (dialog->close);
+}
+
+static void
+selection_changed (GtkTreeView *tree_view, gpointer user_data)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ gchar *name;
+
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter, COLUMN_NAME, &name, -1);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ gtk_widget_hide (dialog->cancel);
+ gtk_widget_show (dialog->close);
+
+ g_signal_emit (dialog, signals[SIGNAL_SHOW], 0, name);
+
+ g_free (name);
+ }
+}
+
+static void
+cancel_clicked (GtkButton *button, gpointer user_data)
+{
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+
+ gtk_widget_hide (dialog->cancel);
+ gtk_widget_show (dialog->close);
+
+ g_signal_emit (dialog, signals[SIGNAL_CANCEL], 0);
+}
+
+static void
+save_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeModel *model;
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+ GtkWidget *name_dialog;
+ GtkWidget *label, *image, *hbox, *vbox, *desc_entry;
+ gchar *name;
+ gint result;
+
+ 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_SAVE, 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 (_("Stash description:"));
+ 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);
+
+ desc_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), desc_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 (desc_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));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_SAVE], 0, name);
+
+ g_free (name);
+}
+
+static void
+apply_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ gchar *name;
+
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+
+ 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_NAME, &name, -1);
+
+ 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));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_APPLY], 0, name);
+
+ g_free (name);
+ }
+}
+
+static void
+pop_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ gchar *name;
+
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+
+ 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_NAME, &name, -1);
+
+ 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));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_POP], 0, name);
+
+ g_free (name);
+ }
+}
+
+static void
+drop_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ gchar *name;
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+ GtkWidget *sure_dialog;
+ gint result;
+
+ 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_NAME, &name, -1);
+
+ sure_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Are you sure you want to drop %s?"), name);
+ result = gtk_dialog_run (GTK_DIALOG (sure_dialog));
+ gtk_widget_destroy (sure_dialog);
+ if (result != GTK_RESPONSE_YES)
+ return;
+
+ 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));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_DROP], 0, name);
+
+ g_free (name);
+ }
+}
+
+static void
+clear_clicked (GtkButton *button, gpointer user_data)
+{
+ GtkTreeModel *model;
+ TghStashDialog *dialog = TGH_STASH_DIALOG (user_data);
+ GtkWidget *sure_dialog;
+ gint result;
+
+ sure_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Are you sure you want to clear all stash?"));
+ result = gtk_dialog_run (GTK_DIALOG (sure_dialog));
+ gtk_widget_destroy (sure_dialog);
+ if (result != GTK_RESPONSE_YES)
+ return;
+
+ 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));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ g_signal_emit (dialog, signals[SIGNAL_CLEAR], 0);
+}
+
diff --git a/tvp-git-helper/tgh-stash-dialog.h b/tvp-git-helper/tgh-stash-dialog.h
new file mode 100644
index 0000000..567297e
--- /dev/null
+++ b/tvp-git-helper/tgh-stash-dialog.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2006 Peter de Ridder <peter at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __TGH_STASH_DIALOG_H__
+#define __TGH_STASH_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _TghStashDialogClass TghStashDialogClass;
+typedef struct _TghStashDialog TghStashDialog;
+
+#define TGH_TYPE_STASH_DIALOG (tgh_stash_dialog_get_type ())
+#define TGH_STASH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TGH_TYPE_STASH_DIALOG, TghStashDialog))
+#define TGH_STASH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TGH_TYPE_STASH_DIALOG, TghStashDialogClass))
+#define TGH_IS_STASH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TGH_TYPE_STASH_DIALOG))
+#define TGH_IS_STASH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TGH_TYPE_STASH_DIALOG))
+#define TGH_STASH_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TGH_TYPE_STASH_DIALOG, TghStashDialogClass))
+
+GType tgh_stash_dialog_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+GtkWidget* tgh_stash_dialog_new (const gchar *title,
+ GtkWindow *parent,
+ GtkDialogFlags flags) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+void tgh_stash_dialog_add (TghStashDialog *dialog,
+ const gchar *name,
+ const gchar *branch,
+ const gchar *description);
+void tgh_stash_dialog_add_file (TghStashDialog *dialog,
+ guint insertions,
+ guint deletions,
+ const gchar *file);
+void tgh_stash_dialog_done (TghStashDialog *dialog);
+
+G_END_DECLS;
+
+#endif /* !__TGH_STASH_DIALOG_H__ */
diff --git a/tvp-git-helper/tgh-stash.c b/tvp-git-helper/tgh-stash.c
new file mode 100644
index 0000000..ee87cd9
--- /dev/null
+++ b/tvp-git-helper/tgh-stash.c
@@ -0,0 +1,377 @@
+/*-
+ * This program 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.
+ *
+ * This program 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
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <thunar-vfs/thunar-vfs.h>
+
+#include "tgh-common.h"
+#include "tgh-dialog-common.h"
+#include "tgh-stash-dialog.h"
+
+#include "tgh-stash.h"
+
+struct exit_args
+{
+ TghOutputParser *parser;
+ TghStashDialog *dialog;
+};
+
+static gboolean stash_list_spawn (TghStashDialog *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 (stash_list_spawn (args->dialog, &pid))
+ tgh_replace_child (TRUE, pid);
+ else
+ tgh_stash_dialog_done (args->dialog);
+
+ g_free (args);
+}
+
+static gchar *argv_list[] = {"git", "stash", "list", NULL};
+static gchar *argv_clear[] = {"git", "stash", "clear", NULL};
+
+static gboolean stash_list_spawn (TghStashDialog *dialog, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_out, fd_err;
+ GIOChannel *chan_out, *chan_err;
+ TghOutputParser *parser;
+
+ if(!g_spawn_async_with_pipes(NULL, argv_list, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, &fd_out, &fd_err, &error))
+ {
+ return FALSE;
+ }
+
+ parser = tgh_error_parser_new(GTK_WIDGET(dialog));
+
+ g_child_watch_add(*pid, (GChildWatchFunc)tgh_child_exit, parser);
+
+ chan_out = g_io_channel_unix_new(fd_out);
+ chan_err = g_io_channel_unix_new(fd_err);
+ g_io_add_watch(chan_out, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, tgh_stash_list_parser_new(GTK_WIDGET(dialog)));
+ g_io_add_watch(chan_err, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, parser);
+
+ return TRUE;
+}
+
+static gboolean stash_show_spawn (TghStashDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_out, fd_err;
+ GIOChannel *chan_out, *chan_err;
+ TghOutputParser *parser;
+ gchar **argv;
+
+ argv = g_new (gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "stash";
+ argv[2] = "show";
+ argv[3] = "--numstat";
+ argv[4] = (gchar*)name;
+ argv[5] = NULL;
+
+ 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))
+ {
+ g_free (argv);
+ return FALSE;
+ }
+ g_free (argv);
+
+ parser = tgh_error_parser_new (GTK_WIDGET (dialog));
+
+ g_child_watch_add (*pid, (GChildWatchFunc)tgh_child_exit, parser);
+
+ chan_out = g_io_channel_unix_new (fd_out);
+ chan_err = g_io_channel_unix_new (fd_err);
+ g_io_add_watch (chan_out, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, tgh_stash_show_parser_new (GTK_WIDGET (dialog)));
+ g_io_add_watch (chan_err, G_IO_IN|G_IO_HUP, (GIOFunc)tgh_parse_output_func, parser);
+
+ return TRUE;
+}
+
+static gboolean stash_save_spawn (TghStashDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "stash";
+ argv[2] = "save";
+ argv[3] = "-q";
+ argv[4] = (gchar*)name;
+ argv[5] = NULL;
+
+ if (!g_spawn_async_with_pipes (NULL, 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 stash_apply_spawn (TghStashDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "stash";
+ argv[2] = "apply";
+ argv[3] = "-q";
+ argv[4] = (gchar*)name;
+ argv[5] = NULL;
+
+ if (!g_spawn_async_with_pipes (NULL, 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 stash_pop_spawn (TghStashDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "stash";
+ argv[2] = "pop";
+ argv[3] = "-q";
+ argv[4] = (gchar*)name;
+ argv[5] = NULL;
+
+ if (!g_spawn_async_with_pipes (NULL, 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 stash_drop_spawn (TghStashDialog *dialog, const gchar *name, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ gchar **argv;
+ struct exit_args *args;
+
+ argv = g_new (gchar*, 6);
+
+ argv[0] = "git";
+ argv[1] = "stash";
+ argv[2] = "drop";
+ argv[3] = "-q";
+ argv[4] = (gchar*)name;
+ argv[5] = NULL;
+
+ if (!g_spawn_async_with_pipes (NULL, 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 stash_clear_spawn (TghStashDialog *dialog, GPid *pid)
+{
+ GError *error = NULL;
+ gint fd_err;
+ GIOChannel *chan_err;
+ TghOutputParser *parser;
+ struct exit_args *args;
+
+ if (!g_spawn_async_with_pipes (NULL, argv_clear, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, pid, NULL, NULL, &fd_err, &error))
+ return FALSE;
+
+ 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 show_stash (TghStashDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (stash_show_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+static void save_stash (TghStashDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (stash_save_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+static void apply_stash (TghStashDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (stash_apply_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+static void pop_stash (TghStashDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (stash_pop_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+static void drop_stash (TghStashDialog *dialog, const gchar *name, gpointer user_data)
+{
+ GPid pid;
+ if (stash_drop_spawn(dialog, name, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+static void clear_stash (TghStashDialog *dialog, gpointer user_data)
+{
+ GPid pid;
+ if (stash_clear_spawn(dialog, &pid))
+ tgh_replace_child(TRUE, pid);
+ else
+ tgh_stash_dialog_done(dialog);
+}
+
+gboolean tgh_stash (gchar **files, GPid *pid)
+{
+ GtkWidget *dialog;
+
+ dialog = tgh_stash_dialog_new (NULL, NULL, 0);
+ g_signal_connect(dialog, "cancel-clicked", tgh_cancel, NULL);
+ tgh_dialog_start (GTK_DIALOG (dialog), TRUE);
+
+ if (files)
+ if (chdir(files[0]))
+ return FALSE;
+
+ g_signal_connect(dialog, "selection-changed", G_CALLBACK (show_stash), NULL);
+ g_signal_connect(dialog, "save-clicked", G_CALLBACK (save_stash), NULL);
+ g_signal_connect(dialog, "apply-clicked", G_CALLBACK (apply_stash), NULL);
+ g_signal_connect(dialog, "pop-clicked", G_CALLBACK (pop_stash), NULL);
+ g_signal_connect(dialog, "drop-clicked", G_CALLBACK (drop_stash), NULL);
+ g_signal_connect(dialog, "clear-clicked", G_CALLBACK (clear_stash), NULL);
+
+ return stash_list_spawn(TGH_STASH_DIALOG(dialog), pid);
+}
+
diff --git a/tvp-git-helper/tgh-log.h b/tvp-git-helper/tgh-stash.h
similarity index 87%
copy from tvp-git-helper/tgh-log.h
copy to tvp-git-helper/tgh-stash.h
index 4dc7265..7df453c 100644
--- a/tvp-git-helper/tgh-log.h
+++ b/tvp-git-helper/tgh-stash.h
@@ -14,14 +14,14 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __TGH_LOG_H__
-#define __TGH_LOG_H__
+#ifndef __TGH_STASH_H__
+#define __TGH_STASH_H__
G_BEGIN_DECLS
-gboolean tgh_log (gchar**, GPid*);
+gboolean tgh_stash (gchar**, GPid*);
G_END_DECLS
-#endif /*__TGH_LOG_H__*/
+#endif /*__TGH_STASH_H__*/
More information about the Xfce4-commits
mailing list