[gitg] Implemented basic drag and drop between staged/unstaged
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Subject: [gitg] Implemented basic drag and drop between staged/unstaged
- Date: Thu, 23 Apr 2009 07:26:42 -0400 (EDT)
commit 405bc8bca13092b22f80bacdaf24b2a3c69d71ed
Author: Jesse van den Kieboom <jesse icecrew nl>
Date: Thu Apr 23 09:39:29 2009 +0200
Implemented basic drag and drop between staged/unstaged
The selection in the treeviews is still only single, so that needs to be fixed
---
gitg/gitg-commit-view.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
gitg/gitg-commit.c | 18 ++++++
gitg/gitg-commit.h | 1 +
3 files changed, 163 insertions(+), 0 deletions(-)
diff --git a/gitg/gitg-commit-view.c b/gitg/gitg-commit-view.c
index f35530e..f7417e1 100644
--- a/gitg/gitg-commit-view.c
+++ b/gitg/gitg-commit-view.c
@@ -671,6 +671,147 @@ initialize_buffer(GitgCommitView *view)
return buffer;
}
+static GtkTargetEntry dnd_entries[] = {
+ {"text/uri-list", 0, 1}
+};
+
+static void
+on_tree_view_drag_data_get (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection,
+ guint info,
+ guint time,
+ GitgCommitView *view)
+{
+ GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+ GtkTreeModel *model;
+ GList *selected = gtk_tree_selection_get_selected_rows(sel, &model);
+ GList *item;
+ gchar **uris = g_new(gchar *, g_list_length(selected) + 1);
+ guint i = 0;
+
+ for (item = selected; item; item = g_list_next(item))
+ {
+ GitgChangedFile *file;
+ GFile *gf;
+ GtkTreeIter iter;
+
+ gtk_tree_model_get_iter(model, &iter, (GtkTreePath *)item->data);
+ gtk_tree_model_get(model, &iter, COLUMN_FILE, &file, -1);
+
+ gf = gitg_changed_file_get_file(file);
+
+ uris[i++] = g_file_get_uri(gf);
+ }
+
+ uris[i] = NULL;
+ gtk_selection_data_set_uris(selection, uris);
+
+ g_strfreev(uris);
+
+ g_list_foreach(selected, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free(selected);
+}
+
+static void
+on_tree_view_staged_drag_data_received(GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ GitgCommitView *view)
+{
+ /* Stage all the files dropped on this */
+ gchar **uris = gtk_selection_data_get_uris(data);
+ gchar **uri;
+ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
+
+ for (uri = uris; *uri; ++uri)
+ {
+ GFile *file = g_file_new_for_uri(*uri);
+ GitgChangedFile *f;
+
+ f = gitg_commit_find_changed_file(view->priv->commit, file);
+
+ if (f && (gitg_changed_file_get_changes(f) & GITG_CHANGED_FILE_CHANGES_UNSTAGED))
+ {
+ gitg_commit_stage(view->priv->commit, f, NULL, NULL);
+ }
+
+ g_object_unref(f);
+ g_object_unref(file);
+ }
+}
+
+static void
+on_tree_view_unstaged_drag_data_received(GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ GitgCommitView *view)
+{
+ /* Unstage all the files dropped on this */
+ gchar **uris = gtk_selection_data_get_uris(data);
+ gchar **uri;
+
+ for (uri = uris; *uri; ++uri)
+ {
+ GFile *file = g_file_new_for_uri(*uri);
+ GitgChangedFile *f;
+
+ f = gitg_commit_find_changed_file(view->priv->commit, file);
+
+ if (f && (gitg_changed_file_get_changes(f) & GITG_CHANGED_FILE_CHANGES_CACHED))
+ {
+ gitg_commit_unstage(view->priv->commit, f, NULL, NULL);
+ }
+
+ g_object_unref(f);
+ g_object_unref(file);
+ }
+}
+
+static void
+initialize_dnd(GitgCommitView *view,
+ GtkTreeView *tree_view,
+ GCallback drag_data_received)
+{
+ gtk_tree_view_enable_model_drag_dest(tree_view,
+ dnd_entries,
+ G_N_ELEMENTS(dnd_entries),
+ GDK_ACTION_COPY);
+
+ gtk_tree_view_enable_model_drag_source(tree_view,
+ GDK_BUTTON1_MASK,
+ dnd_entries,
+ G_N_ELEMENTS(dnd_entries),
+ GDK_ACTION_COPY);
+
+ g_signal_connect(tree_view, "drag-data-get", G_CALLBACK(on_tree_view_drag_data_get), view);
+ g_signal_connect(tree_view, "drag-data-received", G_CALLBACK(drag_data_received), view);
+}
+
+static void
+initialize_dnd_staged(GitgCommitView *view)
+{
+ initialize_dnd(view,
+ view->priv->tree_view_staged,
+ G_CALLBACK(on_tree_view_staged_drag_data_received));
+}
+
+static void
+initialize_dnd_unstaged(GitgCommitView *view)
+{
+ initialize_dnd(view,
+ view->priv->tree_view_unstaged,
+ G_CALLBACK(on_tree_view_unstaged_drag_data_received));
+}
+
static void
gitg_commit_view_parser_finished(GtkBuildable *buildable, GtkBuilder *builder)
{
@@ -697,6 +838,9 @@ gitg_commit_view_parser_finished(GtkBuildable *buildable, GtkBuilder *builder)
self->priv->hscale_context = GTK_HSCALE(gtk_builder_get_object(builder, "hscale_context"));
self->priv->group_context = GTK_ACTION_GROUP(gtk_builder_get_object(builder, "action_group_commit_context"));
+ initialize_dnd_staged(self);
+ initialize_dnd_unstaged(self);
+
GtkIconTheme *theme = gtk_icon_theme_get_default();
GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(theme, GTK_STOCK_ADD, 12, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
diff --git a/gitg/gitg-commit.c b/gitg/gitg-commit.c
index f8125a3..c62a856 100644
--- a/gitg/gitg-commit.c
+++ b/gitg/gitg-commit.c
@@ -870,3 +870,21 @@ on_changed_file_changed(GitgChangedFile *file, GitgCommit *commit)
{
refresh_changes(commit, file);
}
+
+GitgChangedFile *
+gitg_commit_find_changed_file(GitgCommit *commit, GFile *file)
+{
+ g_return_val_if_fail(GITG_IS_COMMIT(commit), NULL);
+ g_return_val_if_fail(G_IS_FILE(file), NULL);
+
+ GitgChangedFile *f = g_hash_table_lookup(commit->priv->files, file);
+
+ if (f != NULL)
+ {
+ return g_object_ref(f);
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/gitg/gitg-commit.h b/gitg/gitg-commit.h
index e5a4b10..d37fc2f 100644
--- a/gitg/gitg-commit.h
+++ b/gitg/gitg-commit.h
@@ -77,6 +77,7 @@ gboolean gitg_commit_commit(GitgCommit *commit, gchar const *comment, gboolean s
gboolean gitg_commit_revert(GitgCommit *commit, GitgChangedFile *file, gchar const *hunk, GError **error);
gboolean gitg_commit_add_ignore(GitgCommit *commit, GitgChangedFile *file, GError **error);
+GitgChangedFile *gitg_commit_find_changed_file(GitgCommit *commit, GFile *file);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]