From 93cb803572c7014c615a608318bef0c062eb7b55 Mon Sep 17 00:00:00 2001 From: James Liggett Date: Sat, 2 Aug 2008 18:17:37 -0700 Subject: [PATCH] Support individual files and folders in log output. Also added the beginnings of file manager integration --- plugins/git/anjuta-git.glade | 13 ++-- plugins/git/anjuta-git.ui | 8 +++ plugins/git/git-log-command.c | 10 +++ plugins/git/git-log-command.h | 1 + plugins/git/git-log-dialog.c | 138 ++++++++++++++++++++++++++++++------------ plugins/git/git-log-dialog.h | 4 -- plugins/git/git-ui-utils.h | 2 +- plugins/git/plugin.c | 83 ++++++++++++++++++++++++- plugins/git/plugin.h | 3 + 9 files changed, 210 insertions(+), 52 deletions(-) diff --git a/plugins/git/anjuta-git.glade b/plugins/git/anjuta-git.glade index f76607a3..d93373d0 100644 --- a/plugins/git/anjuta-git.glade +++ b/plugins/git/anjuta-git.glade @@ -1,6 +1,6 @@ - + @@ -1641,20 +1641,21 @@ True 2 - + True - False 4 + True - + True + False True - + True True True @@ -1694,7 +1695,7 @@ - + True True Whole project diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui index 57100e88..bbfd47ea 100644 --- a/plugins/git/anjuta-git.ui +++ b/plugins/git/anjuta-git.ui @@ -75,4 +75,12 @@ + + + + + + + + diff --git a/plugins/git/git-log-command.c b/plugins/git/git-log-command.c index 685cb4d5..e9df369f 100644 --- a/plugins/git/git-log-command.c +++ b/plugins/git/git-log-command.c @@ -40,6 +40,7 @@ struct _GitLogCommandPriv GRegex *author_regex; GRegex *time_regex; GRegex *short_log_regex; + gchar *path; /* Filters */ gchar *author; @@ -88,6 +89,7 @@ git_log_command_finalize (GObject *object) g_regex_unref (self->priv->author_regex); g_regex_unref (self->priv->time_regex); g_regex_unref (self->priv->short_log_regex); + g_free (self->priv->path); g_free (self->priv->author); g_free (self->priv->grep); @@ -165,6 +167,12 @@ git_log_command_run (AnjutaCommand *command) else git_command_add_arg (GIT_COMMAND (command), "HEAD"); + if (self->priv->path) + { + git_command_add_arg (GIT_COMMAND (command), "--"); + git_command_add_arg (GIT_COMMAND (command), self->priv->path); + } + return 0; } @@ -277,6 +285,7 @@ git_log_command_class_init (GitLogCommandClass *klass) GitLogCommand * git_log_command_new (const gchar *working_directory, + const gchar *path, const gchar *author, const gchar *grep, const gchar *since_date, const gchar *until_date, const gchar *since_commit, @@ -290,6 +299,7 @@ git_log_command_new (const gchar *working_directory, NULL); self->priv->author = g_strdup (author); + self->priv->path = g_strdup (path); self->priv->grep = g_strdup (grep); self->priv->since_date = g_strdup (since_date); self->priv->until_date = g_strdup (until_date); diff --git a/plugins/git/git-log-command.h b/plugins/git/git-log-command.h index e9b7b5ab..d0811ddc 100644 --- a/plugins/git/git-log-command.h +++ b/plugins/git/git-log-command.h @@ -57,6 +57,7 @@ struct _GitLogCommand GType git_log_command_get_type (void) G_GNUC_CONST; GitLogCommand *git_log_command_new (const gchar *working_directory, + const gchar *path, const gchar *author, const gchar *grep, const gchar *since_date, diff --git a/plugins/git/git-log-dialog.c b/plugins/git/git-log-dialog.c index 11a5b5db..658d15d2 100644 --- a/plugins/git/git-log-dialog.c +++ b/plugins/git/git-log-dialog.c @@ -197,25 +197,19 @@ on_log_command_finished (AnjutaCommand *command, guint return_code, LogData *data) { GtkWidget *log_changes_view; - GtkTreeViewColumn *graph_column; GQueue *queue; GtkTreeIter iter; GitRevision *revision; - log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view"); - - /* If the user is using any filters, hide the graph column, because - * we can't be assured that the graph will be correct with filtered output - * and Giggle's graph renderer doesn't seem to be written to handle this - * case, so it might crash when rendering. FIXME: look into improving it; - * qgit can handle this somewhat, maybe look there? */ - graph_column = gtk_tree_view_get_column (GTK_TREE_VIEW (log_changes_view), - 1); + if (return_code != 0) + { + git_report_errors (command, return_code); + g_object_unref (command); + + return; + } - if (g_hash_table_size (data->filters) > 0) - gtk_tree_view_column_set_visible (graph_column, FALSE); - else - gtk_tree_view_column_set_visible (graph_column, TRUE); + log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view"); g_object_ref (data->list_store); gtk_tree_view_set_model (GTK_TREE_VIEW (log_changes_view), NULL); @@ -245,6 +239,10 @@ static void on_ref_command_finished (AnjutaCommand *command, guint return_code, LogData *data) { + gchar *path; + const gchar *relative_path; + GtkWidget *log_changes_view; + GtkTreeViewColumn *graph_column; gchar *author; gchar *grep; gchar *since_date; @@ -254,6 +252,35 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code, GitLogCommand *log_command; gint pulse_timer_id; + path = g_object_get_data (G_OBJECT (command), "path"); + relative_path = NULL; + + if (return_code != 0) + { + git_report_errors (command, return_code); + g_object_unref (command); + + return; + } + + if (path) + { + relative_path = git_get_relative_path (path, + data->plugin->project_root_directory); + } + + /* If the user is using any filters or getting the log of an individual, + * file or folder, hide the graph column, because we can't be assured that + * the graph will be correct in these cases */ + log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view"); + graph_column = gtk_tree_view_get_column (GTK_TREE_VIEW (log_changes_view), + 1); + + if (g_hash_table_size (data->filters) > 0 || path) + gtk_tree_view_column_set_visible (graph_column, FALSE); + else + gtk_tree_view_column_set_visible (graph_column, TRUE); + /* Get the filter data */ author = g_hash_table_lookup (data->filters, "author"); grep = g_hash_table_lookup (data->filters, "grep"); @@ -267,6 +294,7 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code, data->refs = git_ref_command_get_refs (GIT_REF_COMMAND (command)); log_command = git_log_command_new (data->plugin->project_root_directory, + relative_path, author, grep, since_date, until_date, since_commit, until_commit); @@ -290,16 +318,46 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code, } static void -on_view_log_button_clicked (GtkButton *button, LogData *data) +on_log_view_button_clicked (GtkButton *button, LogData *data) { + gchar *path; + GtkWidget *log_window; + GtkWidget *log_whole_project_check; + GtkWidget *log_path_entry; GitRefCommand *ref_command; + path = NULL; + + log_whole_project_check = glade_xml_get_widget (data->gxml, + "log_whole_project_check"); + + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (log_whole_project_check))) + { + log_window = glade_xml_get_widget (data->gxml, "log_window"); + log_path_entry = glade_xml_get_widget (data->gxml, "log_path_entry"); + path = gtk_editable_get_chars (GTK_EDITABLE (log_path_entry), 0, -1); + + if (!git_check_input (log_window, log_path_entry, path, + _("Please enter a path."))) + { + g_free (path); + 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); + + /* Attach path to this command so it can be passed to the log command. */ + g_object_set_data_full (G_OBJECT (ref_command), "path", + g_strdup (path), g_free); + + g_free (path); + anjuta_command_start (ANJUTA_COMMAND (ref_command)); } @@ -695,9 +753,9 @@ git_log_window_create (Git *plugin) GtkWidget *log_window; GtkWidget *log_vbox; GtkWidget *log_changes_view; - GtkWidget *view_log_button; - GtkWidget *whole_project_check; - GtkWidget *path_entry; + GtkWidget *log_view_button; + GtkWidget *log_whole_project_check; + GtkWidget *log_path_entry; GtkTreeSelection *selection; data = g_new0 (LogData, 1); @@ -710,11 +768,11 @@ git_log_window_create (Git *plugin) log_window = glade_xml_get_widget (data->gxml, "log_window"); log_vbox = glade_xml_get_widget (data->gxml, "log_vbox"); log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view"); - whole_project_check = glade_xml_get_widget (data->gxml, - "whole_project_check"); - path_entry = glade_xml_get_widget (data->gxml, "path_entry"); - view_log_button = glade_xml_get_widget (data->gxml, - "view_log_button"); + log_whole_project_check = glade_xml_get_widget (data->gxml, + "log_whole_project_check"); + log_path_entry = glade_xml_get_widget (data->gxml, "log_path_entry"); + log_view_button = glade_xml_get_widget (data->gxml, + "log_view_button"); g_object_set_data (G_OBJECT (log_vbox), "log-data", data); @@ -728,13 +786,13 @@ git_log_window_create (Git *plugin) plugin); - g_signal_connect (G_OBJECT (view_log_button), "clicked", - G_CALLBACK (on_view_log_button_clicked), + g_signal_connect (G_OBJECT (log_view_button), "clicked", + G_CALLBACK (on_log_view_button_clicked), data); - g_object_set_data (G_OBJECT (whole_project_check), "file-entry", - path_entry); - g_signal_connect (G_OBJECT (whole_project_check), "toggled", + g_object_set_data (G_OBJECT (log_whole_project_check), "file-entry", + log_path_entry); + g_signal_connect (G_OBJECT (log_whole_project_check), "toggled", G_CALLBACK (on_git_whole_project_toggled), plugin); data->list_store = gtk_list_store_new (NUM_COLS, @@ -764,23 +822,27 @@ on_menu_git_log (GtkAction *action, Git *plugin) plugin->log_viewer, NULL); } -/* TODO: Enable when FM support is implemented */ -#if 0 void -on_fm_subversion_log (GtkAction *action, Git *plugin) +on_fm_git_log (GtkAction *action, Git *plugin) { - GtkWidget *path_text_entry; - - path_text_entry = glade_xml_get_widget (plugin->log_gxml, - "path_text_entry"); + LogData *data; + GtkWidget *log_path_entry; + GtkWidget *log_whole_project_check; - gtk_entry_set_text (GTK_ENTRY path_entry), - plugin->fm_current_filename); + data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data"); + log_path_entry = glade_xml_get_widget (data->gxml, + "log_path_entry"); + log_whole_project_check = glade_xml_get_widget (data->gxml, + "log_whole_project_check"); + + gtk_entry_set_text (GTK_ENTRY (log_path_entry), + plugin->current_fm_filename); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_whole_project_check), + FALSE); anjuta_shell_present_widget (ANJUTA_PLUGIN (plugin)->shell, plugin->log_viewer, NULL); } -#endif void git_log_window_clear (Git *plugin) diff --git a/plugins/git/git-log-dialog.h b/plugins/git/git-log-dialog.h index 721632aa..0f0986e3 100644 --- a/plugins/git/git-log-dialog.h +++ b/plugins/git/git-log-dialog.h @@ -32,11 +32,7 @@ #include "giggle-graph-renderer.h" void on_menu_git_log (GtkAction* action, Git *plugin); - -/* TODO: Enable when FM support is implemented */ -#if 0 void on_fm_git_log (GtkAction *action, Git *plugin); -#endif GtkWidget *git_log_window_create (Git *plugin); void git_log_window_clear (Git *plugin); diff --git a/plugins/git/git-ui-utils.h b/plugins/git/git-ui-utils.h index 6701d264..82ab2d55 100644 --- a/plugins/git/git-ui-utils.h +++ b/plugins/git/git-ui-utils.h @@ -62,7 +62,7 @@ void git_pulse_progress_bar (GtkProgressBar *progress_bar); void git_report_errors (AnjutaCommand *command, guint return_code); gchar *git_get_filename_from_full_path (gchar *path); const gchar *git_get_relative_path (const gchar *path, - const gchar *working_directory); + const gchar *working_directory); /* Stock signal handlers */ void on_git_command_finished (AnjutaCommand *command, guint return_code, diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c index 0471f783..d2dd7c39 100644 --- a/plugins/git/plugin.c +++ b/plugins/git/plugin.c @@ -385,6 +385,26 @@ static GtkActionEntry actions_log[] = } }; +static GtkActionEntry actions_fm[] = +{ + { + "ActionMenuGitFM", /* Action name */ + NULL, /* Stock icon, if any */ + N_("_Git"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + NULL /* action callback */ + }, + { + "ActionGitFMLog", /* Action name */ + GTK_STOCK_ZOOM_100, /* Stock icon, if any */ + N_("_View log..."), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_fm_git_log) /* action callback */ + } +}; + static void on_project_root_added (AnjutaPlugin *plugin, const gchar *name, const GValue *value, gpointer user_data) @@ -394,6 +414,7 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name, GFile *file; AnjutaUI *ui; GtkAction *git_menu_action; + GtkAction *git_fm_menu_action; git_plugin = ANJUTA_PLUGIN_GIT (plugin); @@ -407,8 +428,12 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name, git_menu_action = anjuta_ui_get_action (ui, "ActionGroupGit", "ActionMenuGit"); + git_fm_menu_action = anjuta_ui_get_action (ui, + "ActionGroupGitFM", + "ActionMenuGitFM"); gtk_action_set_sensitive (git_menu_action, TRUE); + gtk_action_set_sensitive (git_fm_menu_action, TRUE); gtk_widget_set_sensitive (git_plugin->log_viewer, TRUE); g_free (project_root_uri); @@ -420,7 +445,9 @@ static void on_project_root_removed (AnjutaPlugin *plugin, const gchar *name, gpointer user_data) { + AnjutaUI *ui; GtkAction *git_menu_action; + GtkAction *git_fm_menu_action; Git *git_plugin; git_plugin = ANJUTA_PLUGIN_GIT (plugin); @@ -428,12 +455,17 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name, g_free (git_plugin->project_root_directory); git_plugin->project_root_directory = NULL; - git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell, - NULL), + ui = anjuta_shell_get_ui (plugin->shell, NULL); + + git_menu_action = anjuta_ui_get_action (ui, "ActionGroupGit", "ActionMenuGit"); + git_fm_menu_action = anjuta_ui_get_action (ui, + "ActionGroupGitFM", + "ActionMenuGitFM"); gtk_action_set_sensitive (git_menu_action, FALSE); + gtk_action_set_sensitive (git_fm_menu_action, FALSE); gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE); git_log_window_clear (git_plugin); @@ -479,12 +511,39 @@ on_editor_removed (AnjutaPlugin *plugin, const gchar *name, gpointer user_data) git_plugin->current_editor_filename = NULL; } +static void +on_fm_file_added (AnjutaPlugin *plugin, const char *name, + const GValue *value, gpointer data) +{ + Git *git_plugin; + GFile *file; + + git_plugin = ANJUTA_PLUGIN_GIT (plugin); + + g_free (git_plugin->current_fm_filename); + + file = G_FILE (g_value_get_object (value)); + git_plugin->current_fm_filename = g_file_get_path (file); +} + +static void +on_fm_file_removed (AnjutaPlugin *plugin, const char *name, gpointer data) +{ + Git *git_plugin; + + git_plugin = ANJUTA_PLUGIN_GIT (plugin); + + g_free (git_plugin->current_fm_filename); + git_plugin->current_fm_filename = NULL; +} + static gboolean git_activate_plugin (AnjutaPlugin *plugin) { AnjutaUI *ui; Git *git_plugin; GtkAction *git_menu_action; + GtkAction *git_fm_menu_action; DEBUG_PRINT ("Git: Activating Git plugin ..."); @@ -502,11 +561,16 @@ git_activate_plugin (AnjutaPlugin *plugin) actions_log, G_N_ELEMENTS (actions_log), GETTEXT_PACKAGE, TRUE, plugin); + anjuta_ui_add_action_group_entries (ui, "ActionGroupGitFM", + _("Git FM operations"), + actions_fm, + G_N_ELEMENTS (actions_fm), + GETTEXT_PACKAGE, TRUE, plugin); git_plugin->uiid = anjuta_ui_merge (ui, UI_FILE); git_plugin->log_popup_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), - "/PopupLog"); + "/PopupLog"); /* Add watches */ git_plugin->project_root_watch_id = anjuta_plugin_add_watch (plugin, @@ -521,6 +585,12 @@ git_activate_plugin (AnjutaPlugin *plugin) on_editor_removed, NULL); + git_plugin->fm_watch_id = anjuta_plugin_add_watch (plugin, + IANJUTA_FILE_MANAGER_SELECTED_FILE, + on_fm_file_added, + on_fm_file_removed, + NULL); + /* Log viewer */ git_plugin->log_viewer = git_log_window_create (git_plugin); anjuta_shell_add_widget (plugin->shell, @@ -540,10 +610,15 @@ git_activate_plugin (AnjutaPlugin *plugin) NULL), "ActionGroupGit", "ActionMenuGit"); + git_fm_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell, + NULL), + "ActionGroupGitFM", + "ActionMenuGitFM"); if (!git_plugin->project_root_directory) { gtk_action_set_sensitive (git_menu_action, FALSE); + gtk_action_set_sensitive (git_fm_menu_action, FALSE); gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE); } @@ -564,6 +639,8 @@ git_deactivate_plugin (AnjutaPlugin *plugin) TRUE); anjuta_plugin_remove_watch (plugin, git_plugin->editor_watch_id, TRUE); + anjuta_plugin_remove_watch (plugin, git_plugin->fm_watch_id, + TRUE); anjuta_shell_remove_widget (plugin->shell, git_plugin->log_viewer, NULL); gtk_widget_destroy (git_plugin->log_popup_menu); diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h index 7c350cc0..e128fec2 100644 --- a/plugins/git/plugin.h +++ b/plugins/git/plugin.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -51,11 +52,13 @@ struct _Git gint uiid; gchar *project_root_directory; gchar *current_editor_filename; + gchar *current_fm_filename; IAnjutaMessageView *message_view; /* Watches */ gint project_root_watch_id; gint editor_watch_id; + gint fm_watch_id; GtkWidget *log_viewer; GtkWidget *log_popup_menu; -- 2.11.4.GIT