[anjuta] git: Refresh the log view when switching branches (bgo 580276)



commit 2d3ca8d18f092636b581cf39330a0da3fe9281c7
Author: James Liggett <jrliggett cox net>
Date:   Sat Jul 4 18:29:49 2009 -0700

    git: Refresh the log view when switching branches (bgo 580276)

 plugins/git/anjuta-git.ui    |   16 +++--
 plugins/git/git-log-dialog.c |  165 ++++++++++++++++++++++++++++++++++++++----
 plugins/git/git-log-dialog.h |    6 ++
 plugins/git/plugin.c         |    3 +
 plugins/git/plugin.h         |    1 +
 5 files changed, 171 insertions(+), 20 deletions(-)
---
diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui
index a6ffed3..d06774d 100644
--- a/plugins/git/anjuta-git.ui
+++ b/plugins/git/anjuta-git.ui
@@ -3,26 +3,28 @@
   <requires lib="gtk+" version="2.16"/>
   <requires lib="anjuta" version="2366.5320"/>
   <!-- interface-naming-policy project-wide -->
-  <object class="GtkListStore" id="log_branch_combo_model">
+  <object class="GtkListStore" id="branch_list_model">
     <columns>
-      <!-- column-name active_icon -->
-      <column type="gchararray"/>
+      <!-- column-name selected -->
+      <column type="gboolean"/>
       <!-- column-name name -->
       <column type="gchararray"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="branch_list_model">
+  <object class="GtkListStore" id="branch_combo_model">
     <columns>
-      <!-- column-name selected -->
-      <column type="gboolean"/>
       <!-- column-name name -->
       <column type="gchararray"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="branch_combo_model">
+  <object class="GtkListStore" id="log_branch_combo_model">
     <columns>
+      <!-- column-name active_icon -->
+      <column type="gchararray"/>
       <!-- column-name name -->
       <column type="gchararray"/>
+      <!-- column-name active -->
+      <column type="gboolean"/>
     </columns>
   </object>
   <object class="GtkDialog" id="commit_dialog">
diff --git a/plugins/git/git-log-dialog.c b/plugins/git/git-log-dialog.c
index 8a78915..9af98a0 100644
--- a/plugins/git/git-log-dialog.c
+++ b/plugins/git/git-log-dialog.c
@@ -41,6 +41,7 @@ typedef struct
 	gchar *path;
 	GHashTable *refs;
 	GHashTable *filters;
+	gboolean viewing_active_branch;
 } LogData;
 
 static void
@@ -811,6 +812,7 @@ on_log_list_branch_command_data_arrived (AnjutaCommand *command,
 	GitBranch *branch;
 	GtkTreeIter iter;
 	gchar *name;
+	gboolean active;
 	
 	log_branch_combo_model = GTK_LIST_STORE (gtk_builder_get_object (bxml, 
 	                                                                 "log_branch_combo_model"));
@@ -824,20 +826,27 @@ on_log_list_branch_command_data_arrived (AnjutaCommand *command,
 	{
 		branch = g_queue_pop_head (output_queue);
 		name = git_branch_get_name (branch);
+		active = FALSE;
 
 		gtk_list_store_append (log_branch_combo_model, &iter);
 		
 		if (git_branch_is_active (branch))
 		{
-			gtk_list_store_set (log_branch_combo_model, &iter, 0, 
-			                    GTK_STOCK_APPLY, -1);
+			gtk_list_store_set (log_branch_combo_model, &iter,  
+			                    0, GTK_STOCK_APPLY, -1);
 			g_object_set_data_full (G_OBJECT (log_branch_combo), 
 			                        "active-branch-iter",
 			                        g_memdup (&iter, sizeof (GtkTreeIter)), 
 			                        g_free);
+
+			active = TRUE;
 		}
 		
-		gtk_list_store_set (log_branch_combo_model, &iter, 1, name, -1);
+		gtk_list_store_set (log_branch_combo_model, &iter, 
+							1, name,
+		    				2, active, 
+							-1);
+		
 		g_hash_table_insert (branches_table, g_strdup (name), 
 		                     g_memdup (&iter, sizeof (GtkTreeIter)));
 
@@ -848,23 +857,29 @@ on_log_list_branch_command_data_arrived (AnjutaCommand *command,
 
 static void
 on_log_list_branch_command_finished (AnjutaCommand *command, guint return_code,
-                                     GtkBuilder *bxml)
+                                     LogData *data)
 {
 	GtkComboBox *log_branch_combo;
 	GHashTable *branches_table;
 	gchar *selected_branch;
 	GtkTreeIter *iter;
+	GitBranchRefreshFinishCallback finish_callback;
+	gpointer user_data;
 
-	log_branch_combo = GTK_COMBO_BOX (gtk_builder_get_object (bxml,
+	log_branch_combo = GTK_COMBO_BOX (gtk_builder_get_object (data->bxml,
 	                                                          "log_branch_combo"));
 	branches_table = g_object_get_data (G_OBJECT (log_branch_combo),
 	                                    "branches-table");
 	selected_branch = g_object_get_data (G_OBJECT (log_branch_combo),
 	                                     "selected-branch");
 
-	if (selected_branch && g_hash_table_lookup_extended (branches_table, 
-	                                                     selected_branch, NULL,
-		                              					 (gpointer *) &iter))
+	/* If the user was looking at the active branch, switch to the new active
+	 * branch. If the user was looking at another branch, keep it selected if it
+	 * still exists, or just go back to the active branch. */
+	if ((!data->viewing_active_branch) && 
+	    (selected_branch && g_hash_table_lookup_extended (branches_table, 
+	                                                      selected_branch, NULL,
+		                              					  (gpointer *) &iter)))
 	{	
 		gtk_combo_box_set_active_iter (log_branch_combo, iter);
 	}
@@ -876,22 +891,34 @@ on_log_list_branch_command_finished (AnjutaCommand *command, guint return_code,
 	g_object_set_data (G_OBJECT (log_branch_combo), "being-refreshed",
 	                   GINT_TO_POINTER (FALSE));
 
+	finish_callback = g_object_get_data (G_OBJECT (command), "finish-callback");
+	user_data = g_object_get_data (G_OBJECT (command), "user-data");
+
+	if (finish_callback)
+		finish_callback (user_data);
+
 	g_object_unref (command);
 	
 }
 
 static void
-on_log_branch_combo_changed (GtkComboBox *combo_box, gpointer user_data)
+on_log_branch_combo_changed (GtkComboBox *combo_box, LogData *data)
 {
 	GtkTreeModel *log_branch_combo_model;
 	gchar *branch;
 	GtkTreeIter iter;
+	gboolean active;
 
 	log_branch_combo_model = gtk_combo_box_get_model (combo_box);
 
 	if (gtk_combo_box_get_active_iter (combo_box, &iter))
 	{
-		gtk_tree_model_get (log_branch_combo_model, &iter, 1, &branch, -1);
+		gtk_tree_model_get (log_branch_combo_model, &iter, 
+							1, &branch, 
+							2, &active, 
+							-1);
+
+		data->viewing_active_branch = active;
 
 		g_object_set_data_full (G_OBJECT (combo_box), "selected-branch", 
 		                        branch, (GDestroyNotify) g_free);
@@ -910,6 +937,68 @@ on_log_branch_refresh_monitor_changed (GFileMonitor *file_monitor, GFile *file,
 	}
 }
 
+static void 
+log_refresh (LogData *data)
+{
+	GtkComboBox *log_branch_combo;
+	GtkTreeModel *log_branch_combo_model;
+	GtkTreeIter iter;
+	GtkTreeIter first_log_iter;
+	gboolean active;
+	GitRefCommand *ref_command;
+
+	log_branch_combo = GTK_COMBO_BOX (gtk_builder_get_object (data->bxml,
+															  "log_branch_combo"));
+	log_branch_combo_model = GTK_TREE_MODEL (gtk_builder_get_object (data->bxml,
+																	 "log_branch_combo_model"));
+
+	/* Don't refresh the log if the user is looking at an individual path 
+	 * log */
+	if (data->path)
+		return;
+
+	/* Don't refresh the log if the user isn't looking at the active 
+	 * branch */
+	gtk_combo_box_get_active_iter (log_branch_combo, &iter);
+	gtk_tree_model_get (log_branch_combo_model, &iter, 2, &active, -1);
+
+	if (!active)
+		return;
+
+	/* Don't refresh the log if the log view is empty */
+	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (data->list_store), 
+	    &first_log_iter))
+	{
+		return;
+	}	
+
+	ref_command = git_ref_command_new (data->plugin->project_root_directory);
+
+	g_signal_connect (G_OBJECT (ref_command), "command-finished",
+					  G_CALLBACK (on_ref_command_finished),
+					  data);
+
+	anjuta_command_start (ANJUTA_COMMAND (ref_command));
+
+	
+}
+
+static void 
+on_log_refresh_monitor_changed (GFileMonitor *file_monitor, GFile *file,
+								GFile *other_file, GFileMonitorEvent event_type,
+								LogData *data)
+{
+	/* Git must overwrite this file during swtiches instead of just modifying 
+	 * it... */
+	if (event_type == G_FILE_MONITOR_EVENT_CREATED)
+	{
+		/* Always refresh the branch model to at least reflect that the 
+		 * active branch has probably changed */
+		git_log_refresh_branches_full (data->plugin, 
+									   (GitBranchRefreshFinishCallback) log_refresh,
+									   data);
+	}
+}
 
 GtkWidget *
 git_log_window_create (Git *plugin)
@@ -930,6 +1019,10 @@ git_log_window_create (Git *plugin)
 	
 	data = g_new0 (LogData, 1);
 	data->bxml = gtk_builder_new ();
+
+	/* Select the active branch by default */
+	data->viewing_active_branch = TRUE;
+
 	error = NULL;
 
 	if (!gtk_builder_add_objects_from_file (data->bxml, BUILDER_FILE, objects, 
@@ -989,7 +1082,7 @@ git_log_window_create (Git *plugin)
 
 	g_signal_connect (G_OBJECT (log_branch_combo), "changed",
 	                  G_CALLBACK (on_log_branch_combo_changed),
-	                  NULL);
+	                  data);
 	
 	data->list_store = gtk_list_store_new (NUM_COLS,
 										   G_TYPE_OBJECT);
@@ -1063,6 +1156,8 @@ git_log_window_clear (Git *plugin)
 	gtk_list_store_clear (log_branch_combo_model);
 	gtk_text_buffer_set_text (buffer, "", 0);
 
+	data->viewing_active_branch = TRUE;
+
 	g_object_set_data (G_OBJECT (log_branch_combo), "selected-branch", NULL);
 }
 
@@ -1131,8 +1226,40 @@ git_log_setup_branch_refresh_monitor (Git *plugin)
 	return git_ref_monitor;
 }
 
+GFileMonitor *
+git_log_setup_log_refresh_monitor (Git *plugin)
+{
+	gchar *git_head_path;
+	GFile *git_head_file;
+	GFileMonitor *git_head_monitor;
+	LogData *data;
+
+	git_head_path = g_strjoin (G_DIR_SEPARATOR_S,
+	                           plugin->project_root_directory,
+	                           ".git",
+	                           "HEAD",
+	                           NULL);
+
+	git_head_file = g_file_new_for_path (git_head_path);
+	git_head_monitor = g_file_monitor_file (git_head_file, 0, NULL, NULL);
+
+	data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
+	
+
+	g_signal_connect (G_OBJECT (git_head_monitor), "changed",
+	                  G_CALLBACK (on_log_refresh_monitor_changed),
+	                  data);
+
+	g_free (git_head_path);
+	g_object_unref (git_head_file);
+
+	return git_head_monitor;
+}
+
 void
-git_log_refresh_branches (Git *plugin)
+git_log_refresh_branches_full (Git *plugin, 
+							   GitBranchRefreshFinishCallback finish_callback,
+							   gpointer user_data)
 {
 	LogData *data;
 	GtkWidget *log_branch_combo;
@@ -1176,7 +1303,13 @@ git_log_refresh_branches (Git *plugin)
 
 		g_signal_connect (G_OBJECT (branch_list_command), "command-finished",
 		                  G_CALLBACK (on_log_list_branch_command_finished),
-		                  data->bxml);
+		                  data);
+
+		g_object_set_data (G_OBJECT (branch_list_command), "finish-callback",
+						   finish_callback);
+
+		g_object_set_data (G_OBJECT (branch_list_command), "user-data",
+						   user_data);
 
 		g_object_set_data (G_OBJECT (log_branch_combo), "being-refreshed",
 		                   GINT_TO_POINTER (TRUE));
@@ -1185,3 +1318,9 @@ git_log_refresh_branches (Git *plugin)
 	}
 	
 }
+
+void
+git_log_refresh_branches (Git *plugin)
+{
+	git_log_refresh_branches_full (plugin, NULL, NULL);
+}
diff --git a/plugins/git/git-log-dialog.h b/plugins/git/git-log-dialog.h
index 921a162..dfd8be6 100644
--- a/plugins/git/git-log-dialog.h
+++ b/plugins/git/git-log-dialog.h
@@ -31,6 +31,8 @@
 #include "git-ref-command.h"
 #include "giggle-graph-renderer.h"
 
+typedef void (*GitBranchRefreshFinishCallback) (gpointer user_data);
+
 void on_menu_git_log (GtkAction* action, Git *plugin);
 void on_fm_git_log (GtkAction *action, Git *plugin);
 
@@ -39,6 +41,10 @@ void git_log_window_clear (Git *plugin);
 GitRevision *git_log_get_selected_revision (Git *plugin);
 gchar *git_log_get_path (Git *plugin);
 GFileMonitor *git_log_setup_branch_refresh_monitor (Git *plugin);
+GFileMonitor *git_log_setup_log_refresh_monitor (Git *plugin);
+void git_log_refresh_branches_full (Git *plugin,
+									GitBranchRefreshFinishCallback finish_callback,
+									gpointer user_data);
 void git_log_refresh_branches (Git *plugin);
 
 #endif
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index 41b6679..cd1435c 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -548,6 +548,7 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
 	
 	git_plugin->bisect_file_monitor = bisect_menus_init (git_plugin);
 	git_plugin->log_branch_refresh_monitor = git_log_setup_branch_refresh_monitor (git_plugin);
+	git_plugin->log_refresh_monitor = git_log_setup_log_refresh_monitor (git_plugin);
 	git_log_refresh_branches (git_plugin);
 }
 
@@ -581,6 +582,8 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
 	
 	g_file_monitor_cancel (git_plugin->bisect_file_monitor);
 	g_file_monitor_cancel (git_plugin->log_branch_refresh_monitor);
+	g_file_monitor_cancel (git_plugin->log_refresh_monitor);
+	
 	g_object_unref (git_plugin->bisect_file_monitor);
 }
 
diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h
index f4e262d..62402f2 100644
--- a/plugins/git/plugin.h
+++ b/plugins/git/plugin.h
@@ -66,6 +66,7 @@ struct _Git
 	/* File monitors */
 	GFileMonitor *bisect_file_monitor;
 	GFileMonitor *log_branch_refresh_monitor;
+	GFileMonitor *log_refresh_monitor;
 };
 
 struct _GitClass



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