[anjuta/libgit2-glib: 7/14] git: Implement basic automatic refreshing in the status pane
- From: James Liggett <jrliggett src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta/libgit2-glib: 7/14] git: Implement basic automatic refreshing in the status pane
- Date: Tue, 6 Aug 2013 04:42:30 +0000 (UTC)
commit 1ab6987a25fa848b8ebc5e57ed8601fae77afd56
Author: James Liggett <jrliggett cox net>
Date: Wed Jul 24 18:23:10 2013 -0700
git: Implement basic automatic refreshing in the status pane
plugins/git/git-status-pane.c | 164 +++++++++++++++++++++++++++++++++++------
plugins/git/plugin.c | 5 +
plugins/git/plugin.h | 1 +
3 files changed, 148 insertions(+), 22 deletions(-)
---
diff --git a/plugins/git/git-status-pane.c b/plugins/git/git-status-pane.c
index 4004045..b2490cd 100644
--- a/plugins/git/git-status-pane.c
+++ b/plugins/git/git-status-pane.c
@@ -58,6 +58,11 @@ struct _GitStatusPanePriv
{
GtkBuilder *builder;
+ /* Status command. We generate a new one for each refresh, but we don't want
+ * to have more the one refresh happen at once. This value will be NULL when
+ * no status command is running. */
+ GitCommand *status_command;
+
/* Iters for the two sections: Changes to be committed and Changed but not
* updated. Status items will be children of these two iters. */
GtkTreeIter commit_iter;
@@ -66,9 +71,119 @@ struct _GitStatusPanePriv
/* Hash tables that show which items are selected in each section */
GHashTable *selected_commit_items;
GHashTable *selected_not_updated_items;
+
+ /* File monitors */
+ GFileMonitor *head_monitor;
+ GFileMonitor *index_monitor;
};
-G_DEFINE_TYPE (GitStatusPane, git_status_pane, GIT_TYPE_PANE);
+static void
+on_file_monitor_changed (GFileMonitor *monitor, GFile *file, GFile *other_file,
+ GFileMonitorEvent event, AnjutaDockPane *pane)
+{
+ /* Handle created and modified events just to cover all possible cases.
+ * Sometimes git does some odd things... */
+ if (event == G_FILE_MONITOR_EVENT_CHANGED ||
+ event == G_FILE_MONITOR_EVENT_CREATED)
+ {
+ anjuta_dock_pane_refresh (pane);
+ }
+}
+
+static void
+git_status_pane_start_monitor (IAnjutaRefreshable *obj, GError **error)
+{
+ GitStatusPane *self;
+ Git *plugin;
+ const gchar *working_directory;
+ gchar *git_head_path;
+ gchar *git_index_path;
+ GFile *git_head_file;
+ GFile *git_index_file;
+ GError *file_error;
+
+ self = GIT_STATUS_PANE (obj);
+ plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (ANJUTA_DOCK_PANE (obj)));
+ working_directory = plugin->project_root_directory;
+
+ /* Watch for changes to the HEAD file and the index file, so that we can
+ * at least detect commits and index changes. */
+ git_head_path = g_strjoin (G_DIR_SEPARATOR_S,
+ working_directory,
+ ".git",
+ "HEAD",
+ NULL);
+ git_index_path = g_strjoin (G_DIR_SEPARATOR_S,
+ working_directory,
+ ".git",
+ "index",
+ NULL);
+ git_head_file = g_file_new_for_path (git_head_path);
+ git_index_file = g_file_new_for_path (git_index_path);
+
+ self->priv->head_monitor = g_file_monitor_file (git_head_file, 0, NULL,
+ &file_error);
+
+ if (self->priv->head_monitor)
+ {
+ self->priv->index_monitor = g_file_monitor_file (git_index_file, 0, NULL,
+ &file_error);
+
+ if (self->priv->index_monitor)
+ {
+ g_signal_connect (G_OBJECT (self->priv->head_monitor), "changed",
+ G_CALLBACK (on_file_monitor_changed),
+ ANJUTA_DOCK_PANE (obj));
+
+ g_signal_connect (G_OBJECT (self->priv->index_monitor), "changed",
+ G_CALLBACK (on_file_monitor_changed),
+ ANJUTA_DOCK_PANE (obj));
+ }
+ }
+
+
+
+ if (error)
+ *error = g_error_copy (file_error);
+
+ g_error_free (file_error);
+
+ g_free (git_head_path);
+ g_free (git_index_path);
+ g_object_unref (git_head_file);
+ g_object_unref (git_index_file);
+}
+
+static void
+git_status_pane_stop_monitor (IAnjutaRefreshable *obj, GError **error)
+{
+ GitStatusPane *self;
+
+ self = GIT_STATUS_PANE (obj);
+
+ if (self->priv->head_monitor)
+ {
+ g_file_monitor_cancel (self->priv->head_monitor);
+ g_clear_object (&self->priv->head_monitor);
+ }
+
+ if (self->priv->index_monitor)
+ {
+ g_file_monitor_cancel (self->priv->index_monitor);
+ g_clear_object (&self->priv->head_monitor);
+ }
+}
+
+static void
+ianjuta_refreshable_init (IAnjutaRefreshableIface *iface)
+{
+ iface->start_monitor = git_status_pane_start_monitor;
+ iface->stop_monitor = git_status_pane_stop_monitor;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GitStatusPane, git_status_pane, GIT_TYPE_PANE,
+ G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_REFRESHABLE,
+ ianjuta_refreshable_init));
static void
selected_renderer_data_func (GtkTreeViewColumn *tree_column,
@@ -327,8 +442,6 @@ on_status_command_data_arrived (AnjutaTask *task, GitStatusPane *self)
AnjutaVcsStatus index_status;
AnjutaVcsStatus working_tree_status;
- g_print ("Data arrived.\n");
-
status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
"status_model"));
status_queue = git_status_command_get_status_queue (GIT_STATUS_COMMAND (task));
@@ -702,6 +815,9 @@ git_status_pane_finalize (GObject *object)
g_object_unref (self->priv->builder);
g_hash_table_destroy (self->priv->selected_commit_items);
g_hash_table_destroy (self->priv->selected_not_updated_items);
+
+ g_clear_object (&self->priv->index_monitor);
+ g_clear_object (&self->priv->head_monitor);
g_free (self->priv);
G_OBJECT_CLASS (git_status_pane_parent_class)->finalize (object);
@@ -712,33 +828,37 @@ git_status_pane_refresh (AnjutaDockPane *pane)
{
GitStatusPane *self;
Git *plugin;
- GitCommand *status_command;
GtkTreeView *status_view;
self = GIT_STATUS_PANE (pane);
- plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (pane));
- status_command = git_status_command_new (0, NULL);
- status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
- "status_view"));
+
+ if (!self->priv->status_command)
+ {
+ plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (pane));
+ self->priv->status_command = git_status_command_new (0, NULL);
+ status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+ "status_view"));
- git_status_pane_clear (self);
+ git_status_pane_clear (self);
- g_signal_connect (G_OBJECT (status_command), "data-arrived",
- G_CALLBACK (on_status_command_data_arrived),
- pane);
+ g_signal_connect (G_OBJECT (self->priv->status_command), "data-arrived",
+ G_CALLBACK (on_status_command_data_arrived),
+ pane);
- /* Expand the placeholders so something is visible to the user after
- * refreshing */
- g_signal_connect_swapped (G_OBJECT (status_command),
- "finished",
- G_CALLBACK (gtk_tree_view_expand_all),
- status_view);
+ /* Expand the placeholders so something is visible to the user after
+ * refreshing */
+ g_signal_connect_swapped (G_OBJECT (self->priv->status_command),
+ "finished",
+ G_CALLBACK (gtk_tree_view_expand_all),
+ status_view);
- g_signal_connect (G_OBJECT (status_command), "finished",
- G_CALLBACK (g_object_unref),
- NULL);
+ g_signal_connect_swapped (G_OBJECT (self->priv->status_command),
+ "finished",
+ G_CALLBACK (g_clear_object),
+ &self->priv->status_command);
- git_thread_pool_push (plugin->thread_pool, status_command);
+ git_thread_pool_push (plugin->thread_pool, self->priv->status_command);
+ }
}
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index 503bc43..6f27c4d 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -683,6 +683,9 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
"working-directory", git_plugin->project_root_directory,
NULL);
+ ianjuta_refreshable_start_monitor (IANJUTA_REFRESHABLE (git_plugin->status_pane), NULL);
+ anjuta_dock_pane_refresh (git_plugin->status_pane);
+
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->local_branch_list_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->remote_list_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->tag_list_command));
@@ -719,6 +722,8 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
git_plugin->thread_pool = NULL;
git_plugin->repository = NULL;
}
+
+ ianjuta_refreshable_stop_monitor (IANJUTA_REFRESHABLE (git_plugin->status_pane), NULL);
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->local_branch_list_command));
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->remote_list_command));
diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h
index 8368d4a..ee8cdf6 100644
--- a/plugins/git/plugin.h
+++ b/plugins/git/plugin.h
@@ -31,6 +31,7 @@
#include <libanjuta/interfaces/ianjuta-file.h>
#include <libanjuta/interfaces/ianjuta-project-manager.h>
#include <libanjuta/interfaces/ianjuta-file-manager.h>
+#include <libanjuta/interfaces/ianjuta-refreshable.h>
#include <libanjuta/anjuta-shell.h>
#include <libanjuta/anjuta-dock.h>
#include <libanjuta/anjuta-debug.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]