[anjuta] git: Add context menus to the Status pane



commit 04325efbf1cd170d3794583f9da7aad82c4e329b
Author: James Liggett <jrliggett cox net>
Date:   Wed May 8 15:59:19 2013 -0700

    git: Add context menus to the Status pane

 plugins/git/Makefile.am                  |    4 +
 plugins/git/anjuta-git.ui                |    1 +
 plugins/git/anjuta-git.xml               |   10 +++
 plugins/git/git-checkout-pane.c          |   34 +++++++++-
 plugins/git/git-checkout-pane.h          |    1 +
 plugins/git/git-commit-pane.c            |    4 +-
 plugins/git/git-resolve-conflicts-pane.c |    4 +-
 plugins/git/git-status-pane.c            |  107 ++++++++++++++++++++++++++++--
 plugins/git/git-status-pane.h            |   14 ++--
 plugins/git/git-unstage-pane.c           |   35 +++++++++-
 plugins/git/git-unstage-pane.h           |    1 +
 plugins/git/plugin.c                     |   37 ++++++++++
 plugins/git/plugin.h                     |    4 +
 13 files changed, 236 insertions(+), 20 deletions(-)
---
diff --git a/plugins/git/Makefile.am b/plugins/git/Makefile.am
index c77c9bb..4212584 100644
--- a/plugins/git/Makefile.am
+++ b/plugins/git/Makefile.am
@@ -4,6 +4,10 @@ SUBDIRS = images
 git_gladedir = $(anjuta_glade_dir)
 dist_git_glade_DATA = anjuta-git.ui
 
+# Plugin UI file
+git_uidir = $(anjuta_ui_dir)
+dist_git_ui_DATA = anjuta-git.xml
+
 # Plugin description file
 plugin_in_files = git.plugin.in
 %.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) 
$(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui
index 7542d49..456a3bd 100644
--- a/plugins/git/anjuta-git.ui
+++ b/plugins/git/anjuta-git.ui
@@ -3680,6 +3680,7 @@
                   <object class="GtkTreeView" id="status_view">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="events">GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK</property>
                     <property name="model">status_model</property>
                     <property name="headers_visible">False</property>
                     <property name="headers_clickable">False</property>
diff --git a/plugins/git/anjuta-git.xml b/plugins/git/anjuta-git.xml
new file mode 100644
index 0000000..1d20b48
--- /dev/null
+++ b/plugins/git/anjuta-git.xml
@@ -0,0 +1,10 @@
+<!--*- xml -*-->
+<ui>
+    <popup name="GitStatusNotUpdatedPopup">
+        <menuitem name="Check out" action="GitStatusCheckOut" />  
+    </popup>
+
+    <popup name="GitStatusCommitPopup">
+        <menuitem name="Unstage" action="GitStatusUnstage" />    
+    </popup>
+</ui>
\ No newline at end of file
diff --git a/plugins/git/git-checkout-pane.c b/plugins/git/git-checkout-pane.c
index e76e81b..0993273 100644
--- a/plugins/git/git-checkout-pane.c
+++ b/plugins/git/git-checkout-pane.c
@@ -38,8 +38,8 @@ on_ok_action_activated (GtkAction *action, GitCheckoutPane *self)
        force_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (self->priv->builder,
                                                                  "force_action"));
 
-       paths = git_status_pane_get_selected_not_updated_items (GIT_STATUS_PANE (plugin->status_pane),
-                                                               ANJUTA_VCS_STATUS_ALL);
+       paths = git_status_pane_get_checked_not_updated_items (GIT_STATUS_PANE (plugin->status_pane),
+                                                              ANJUTA_VCS_STATUS_ALL);
        checkout_command = git_checkout_files_command_new (plugin->project_root_directory,
                                                           paths,
                                                           gtk_toggle_action_get_active (force_action));
@@ -150,3 +150,33 @@ on_checkout_button_clicked (GtkAction *action, Git *plugin)
                                          _("Check Out Files"), NULL, checkout_pane,
                                          GDL_DOCK_BOTTOM, NULL, 0, NULL);
 }
+
+void
+on_git_status_checkout_activated (GtkAction *action, Git *plugin)
+{
+       gchar *path;
+       GList *paths;
+       GitCheckoutFilesCommand *checkout_command;
+
+       path = git_status_pane_get_selected_not_updated_path (GIT_STATUS_PANE (plugin->status_pane));
+
+       if (path)
+       {
+               paths = g_list_append (NULL, path);
+
+               checkout_command = git_checkout_files_command_new (plugin->project_root_directory,
+                                                                  paths, FALSE);
+
+               g_signal_connect (G_OBJECT (checkout_command), "command-finished",
+                                 G_CALLBACK (git_pane_report_errors),
+                                 plugin);
+
+               g_signal_connect (G_OBJECT (checkout_command), "command-finished",
+                                 G_CALLBACK (g_object_unref),
+                                 NULL);
+
+               anjuta_util_glist_strings_free (paths);
+
+               anjuta_command_start (ANJUTA_COMMAND (checkout_command));
+       }
+}
diff --git a/plugins/git/git-checkout-pane.h b/plugins/git/git-checkout-pane.h
index efd19a3..1606e62 100644
--- a/plugins/git/git-checkout-pane.h
+++ b/plugins/git/git-checkout-pane.h
@@ -53,6 +53,7 @@ struct _GitCheckoutPane
 GType git_checkout_pane_get_type (void) G_GNUC_CONST;
 AnjutaDockPane *git_checkout_pane_new (Git *plugin);
 void on_checkout_button_clicked (GtkAction *action, Git *plugin);
+void on_git_status_checkout_activated (GtkAction *action, Git *plugin);
 
 G_END_DECLS
 
diff --git a/plugins/git/git-commit-pane.c b/plugins/git/git-commit-pane.c
index feb5b4c..58f7f6d 100644
--- a/plugins/git/git-commit-pane.c
+++ b/plugins/git/git-commit-pane.c
@@ -156,8 +156,8 @@ on_ok_action_activated (GtkAction *action, GitCommitPane *self)
                }
        }
 
-       selected_paths = git_status_pane_get_all_selected_items (GIT_STATUS_PANE (plugin->status_pane),
-                                                                ANJUTA_VCS_STATUS_ALL);
+       selected_paths = git_status_pane_get_all_checked_items (GIT_STATUS_PANE (plugin->status_pane),
+                                                               ANJUTA_VCS_STATUS_ALL);
 
        commit_command = git_commit_command_new (plugin->project_root_directory,
                                                 gtk_toggle_button_get_active (amend_check),
diff --git a/plugins/git/git-resolve-conflicts-pane.c b/plugins/git/git-resolve-conflicts-pane.c
index 95964bc..1fac906 100644
--- a/plugins/git/git-resolve-conflicts-pane.c
+++ b/plugins/git/git-resolve-conflicts-pane.c
@@ -25,8 +25,8 @@ on_resolve_conflicts_button_clicked (GtkAction *action, Git *plugin)
        GList *paths;
        GitAddCommand *add_command;
 
-       paths = git_status_pane_get_all_selected_items (GIT_STATUS_PANE (plugin->status_pane),
-                                                       ANJUTA_VCS_STATUS_CONFLICTED);
+       paths = git_status_pane_get_all_checked_items (GIT_STATUS_PANE (plugin->status_pane),
+                                                      ANJUTA_VCS_STATUS_CONFLICTED);
 
        if (paths)
        {
diff --git a/plugins/git/git-status-pane.c b/plugins/git/git-status-pane.c
index f39ae7d..6f74de7 100644
--- a/plugins/git/git-status-pane.c
+++ b/plugins/git/git-status-pane.c
@@ -536,6 +536,58 @@ on_status_view_drag_drop (GtkWidget *widget, GdkDragContext *context,
        return TRUE;
 }
 
+static gboolean
+on_status_view_button_press_event (GtkWidget *widget, GdkEvent *event,
+                                   GitStatusPane *self)
+{
+       GdkEventButton *button_event;
+       AnjutaPlugin *plugin;
+       AnjutaUI *ui;
+       GtkTreeView *status_view;
+       GtkTreeSelection *selection;
+       GtkTreeModel *status_model;
+       GtkTreeIter iter;
+       StatusType status_type;
+       GtkMenu *menu;
+
+       button_event = (GdkEventButton *) event;
+       menu = NULL;
+       
+       if (button_event->type == GDK_BUTTON_PRESS && button_event->button == 3)
+       {
+               plugin = anjuta_dock_pane_get_plugin (ANJUTA_DOCK_PANE (self));
+               ui = anjuta_shell_get_ui (plugin->shell, NULL);
+               status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                                    "status_view"));
+               selection = gtk_tree_view_get_selection (status_view);
+
+               if (gtk_tree_selection_get_selected (selection, &status_model, &iter))
+               {
+                       gtk_tree_model_get (status_model, &iter, COL_TYPE, &status_type, 
+                                           -1);
+
+                       if (status_type == STATUS_TYPE_COMMIT)
+                       {
+                               menu = GTK_MENU (gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
+                                                                                   "/GitStatusCommitPopup"));
+                       }
+                       else if (status_type == STATUS_TYPE_NOT_UPDATED)
+                       {
+                               menu = GTK_MENU (gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
+                                                                                       
"/GitStatusNotUpdatedPopup"));
+                       }
+
+                       if (menu)
+                       {
+                               gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_event->button, 
+                                               button_event->time);
+                       }
+               }
+       }
+
+       return FALSE;
+}
+
 static void
 git_status_pane_init (GitStatusPane *self)
 {
@@ -637,6 +689,11 @@ git_status_pane_init (GitStatusPane *self)
        g_signal_connect (G_OBJECT (status_view), "drag-data-received",
                          G_CALLBACK (on_status_view_drag_data_received),
                          self);
+
+       /* Popup menus */
+       g_signal_connect (G_OBJECT (status_view), "button-press-event",
+                         G_CALLBACK (on_status_view_button_press_event),
+                         self);
 }
 
 static void
@@ -731,8 +788,8 @@ selected_items_table_foreach (gchar *path, gpointer status,
 }
 
 GList *
-git_status_pane_get_selected_commit_items (GitStatusPane *self,
-                                           AnjutaVcsStatus status_codes)
+git_status_pane_get_checked_commit_items (GitStatusPane *self,
+                                          AnjutaVcsStatus status_codes)
 {
        StatusSelectionData data;
 
@@ -747,8 +804,8 @@ git_status_pane_get_selected_commit_items (GitStatusPane *self,
 }
 
 GList *
-git_status_pane_get_selected_not_updated_items (GitStatusPane *self,
-                                                AnjutaVcsStatus status_codes)
+git_status_pane_get_checked_not_updated_items (GitStatusPane *self,
+                                               AnjutaVcsStatus status_codes)
 {
        StatusSelectionData data;
 
@@ -763,8 +820,8 @@ git_status_pane_get_selected_not_updated_items (GitStatusPane *self,
 }
 
 GList *
-git_status_pane_get_all_selected_items (GitStatusPane *self,
-                                        AnjutaVcsStatus status_codes)
+git_status_pane_get_all_checked_items (GitStatusPane *self,
+                                       AnjutaVcsStatus status_codes)
 {
        StatusSelectionData data;
 
@@ -781,3 +838,41 @@ git_status_pane_get_all_selected_items (GitStatusPane *self,
 
        return data.list;
 }
+
+static gchar *
+git_status_pane_get_selected_path (GitStatusPane *self, StatusType type)
+{
+       gchar *path;
+       GtkTreeView *status_view;
+       GtkTreeSelection *selection;
+       GtkTreeModel *status_model;
+       GtkTreeIter iter;
+       StatusType selected_type;
+
+       path = NULL;
+       status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                            "status_view"));
+       selection = gtk_tree_view_get_selection (status_view);
+
+       if (gtk_tree_selection_get_selected (selection, &status_model, &iter))
+       {
+               gtk_tree_model_get (status_model, &iter, COL_TYPE, &selected_type, -1);
+
+               if (type == selected_type)
+                       gtk_tree_model_get (status_model, &iter, COL_PATH, &path, -1);
+       }
+
+       return path;
+}
+
+gchar *
+git_status_pane_get_selected_commit_path (GitStatusPane *self)
+{
+       return git_status_pane_get_selected_path (self, STATUS_TYPE_COMMIT);
+}
+
+gchar *
+git_status_pane_get_selected_not_updated_path (GitStatusPane *self)
+{
+       return git_status_pane_get_selected_path (self, STATUS_TYPE_NOT_UPDATED);
+}
diff --git a/plugins/git/git-status-pane.h b/plugins/git/git-status-pane.h
index cbd126d..c8eeaf0 100644
--- a/plugins/git/git-status-pane.h
+++ b/plugins/git/git-status-pane.h
@@ -52,12 +52,14 @@ struct _GitStatusPane
 
 GType git_status_pane_get_type (void) G_GNUC_CONST;
 AnjutaDockPane *git_status_pane_new (Git *plugin);
-GList *git_status_pane_get_selected_commit_items (GitStatusPane *self,
-                                                  AnjutaVcsStatus status_codes);
-GList *git_status_pane_get_selected_not_updated_items (GitStatusPane *self,
-                                                       AnjutaVcsStatus status_codes);
-GList *git_status_pane_get_all_selected_items (GitStatusPane *self,
-                                               AnjutaVcsStatus status_codes);
+GList *git_status_pane_get_checked_commit_items (GitStatusPane *self,
+                                                 AnjutaVcsStatus status_codes);
+GList *git_status_pane_get_checked_not_updated_items (GitStatusPane *self,
+                                                      AnjutaVcsStatus status_codes);
+GList *git_status_pane_get_all_checked_items (GitStatusPane *self,
+                                              AnjutaVcsStatus status_codes);
+gchar *git_status_pane_get_selected_commit_path (GitStatusPane *self);
+gchar *git_status_pane_get_selected_not_updated_path (GitStatusPane *self);
 
 G_END_DECLS
 
diff --git a/plugins/git/git-unstage-pane.c b/plugins/git/git-unstage-pane.c
index 152f91d..f8f4e9e 100644
--- a/plugins/git/git-unstage-pane.c
+++ b/plugins/git/git-unstage-pane.c
@@ -25,8 +25,8 @@ on_unstage_button_clicked (GtkAction *action, Git *plugin)
        GList *paths;
        GitResetFilesCommand *reset_command;
 
-       paths = git_status_pane_get_selected_commit_items (GIT_STATUS_PANE (plugin->status_pane),
-                                                          ANJUTA_VCS_STATUS_ALL);
+       paths = git_status_pane_get_checked_commit_items (GIT_STATUS_PANE (plugin->status_pane),
+                                                         ANJUTA_VCS_STATUS_ALL);
 
        if (paths)
        {
@@ -50,4 +50,35 @@ on_unstage_button_clicked (GtkAction *action, Git *plugin)
        else
                anjuta_util_dialog_error (NULL, _("No staged files selected."));
 }
+
+void
+on_git_status_unstage_activated (GtkAction *action, Git *plugin)
+{
+       gchar *path;
+       GList *paths;
+       GitResetFilesCommand *reset_command;
+
+       path = git_status_pane_get_selected_commit_path (GIT_STATUS_PANE (plugin->status_pane));
+
+       if (path)
+       {
+               paths = g_list_append (NULL, path);
+
+               reset_command = git_reset_files_command_new (plugin->project_root_directory,
+                                                            GIT_RESET_FILES_HEAD,
+                                                            paths);
+
+               g_signal_connect (G_OBJECT (reset_command), "command-finished",
+                                 G_CALLBACK (git_pane_report_errors),
+                                 plugin);
+
+               g_signal_connect (G_OBJECT (reset_command), "command-finished",
+                                 G_CALLBACK (g_object_unref),
+                                 NULL);
+
+               anjuta_util_glist_strings_free (paths);
+
+               anjuta_command_start (ANJUTA_COMMAND (reset_command));
+       }
+}
  
\ No newline at end of file
diff --git a/plugins/git/git-unstage-pane.h b/plugins/git/git-unstage-pane.h
index 8f02c00..23ce841 100644
--- a/plugins/git/git-unstage-pane.h
+++ b/plugins/git/git-unstage-pane.h
@@ -24,5 +24,6 @@
 #include "git-status-pane.h"
 
 void on_unstage_button_clicked (GtkAction *action, Git *plugin);
+void on_git_status_unstage_activated (GtkAction *action, Git *plugin);
 
 #endif
\ No newline at end of file
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index 808a06a..90cd4cf 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -58,6 +58,7 @@
 #include "git-apply-mailbox-pane.h"
 
 #define SETTINGS_SCHEMA "org.gnome.anjuta.plugins.git"
+#define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-git.xml"
 
 AnjutaCommandBarEntry branch_entries[] =
 {
@@ -484,6 +485,26 @@ static AnjutaCommandBarEntry log_entries[] =
        }
 };
 
+static GtkActionEntry status_menu_entries[] = 
+{
+       {
+               "GitStatusCheckOut",
+               NULL,
+               N_("Check out"),
+               NULL,
+               NULL,
+               G_CALLBACK (on_git_status_checkout_activated)
+       },
+       {
+               "GitStatusUnstage",
+               NULL,
+               N_("Unstage"),
+               NULL,
+               NULL,
+               G_CALLBACK (on_git_status_unstage_activated)
+       }
+};
+
 static gpointer parent_class;
 
 static void
@@ -680,6 +701,7 @@ git_activate_plugin (AnjutaPlugin *plugin)
        gchar *objects[] = {"grip_box",
                                                NULL};
        GtkWidget *git_tasks_button;
+       AnjutaUI *ui;
        
        DEBUG_PRINT ("%s", "Git: Activating Git plugin …");
        
@@ -719,6 +741,16 @@ git_activate_plugin (AnjutaPlugin *plugin)
        g_settings_bind (git_plugin->settings, "show-command-bar", 
                         git_tasks_button, "active", G_SETTINGS_BIND_DEFAULT);
 
+       /* Pop up menus */
+       ui = anjuta_shell_get_ui (plugin->shell, NULL);
+
+       git_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
+       git_plugin->status_menu_group = anjuta_ui_add_action_group_entries (ui, "GitStatusPopup", 
+                                                                           _("Status popup menu"), 
+                                                                           status_menu_entries, 
+                                                                           G_N_ELEMENTS 
(status_menu_entries), 
+                                                                           GETTEXT_PACKAGE, FALSE, plugin);
+
        
        /* Create the branch list commands. There are two commands because some 
         * views need to be able to tell the difference between local and 
@@ -842,6 +874,7 @@ static gboolean
 git_deactivate_plugin (AnjutaPlugin *plugin)
 {
        Git *git_plugin;
+       AnjutaUI *ui;
        
        git_plugin = ANJUTA_PLUGIN_GIT (plugin);
        
@@ -854,6 +887,10 @@ git_deactivate_plugin (AnjutaPlugin *plugin)
 
        anjuta_shell_remove_widget (plugin->shell, git_plugin->box, NULL);
 
+       ui = anjuta_shell_get_ui (plugin->shell, NULL);
+       anjuta_ui_remove_action_group (ui, git_plugin->status_menu_group);
+       anjuta_ui_unmerge (ui, git_plugin->uiid);
+
        g_object_unref (git_plugin->local_branch_list_command);
        g_object_unref (git_plugin->remote_branch_list_command);
        g_object_unref (git_plugin->commit_status_command);
diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h
index 647d99c..4b3074b 100644
--- a/plugins/git/plugin.h
+++ b/plugins/git/plugin.h
@@ -77,6 +77,10 @@ struct _Git
        AnjutaDockPane *remotes_pane;
        AnjutaDockPane *stash_pane;
 
+       /* Popup menu action groups */
+       gint uiid;
+       GtkActionGroup *status_menu_group;
+
        /* List commands for various panes. 
         * Keep them in the plugin so that the commands have the most direct
         * way of handling project (working directory) changes */


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