[anjuta] git: Show diffs of uncommitted changes in the status view



commit b65b428b3d59945fcaec9970eae3cc6098ab35f4
Author: James Liggett <jrliggett cox net>
Date:   Sat Aug 17 17:11:24 2013 -0700

    git: Show diffs of uncommitted changes in the status view

 plugins/git/anjuta-git.ui                          |   21 ++-
 plugins/git/git-diff-command.c                     |   37 +++-
 plugins/git/git-diff-command.h                     |   12 +-
 plugins/git/git-diff-pane.c                        |   31 ---
 plugins/git/git-status-pane.c                      |  263 +++++++++++++++++---
 plugins/git/git-status-pane.h                      |    2 +
 plugins/git/git-vcs-interface.c                    |    2 +-
 .../org.gnome.anjuta.plugins.git.gschema.xml.in    |    5 +-
 plugins/git/plugin.c                               |    8 -
 9 files changed, 300 insertions(+), 81 deletions(-)
---
diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui
index 456a3bd..6b1f209 100644
--- a/plugins/git/anjuta-git.ui
+++ b/plugins/git/anjuta-git.ui
@@ -3653,6 +3653,8 @@
       <column type="gint"/>
       <!-- column-name path -->
       <column type="gchararray"/>
+      <!-- column-name diff -->
+      <column type="gchararray"/>
       <!-- column-name type -->
       <column type="gint"/>
     </columns>
@@ -3735,6 +3737,19 @@
         <property name="spacing">5</property>
         <property name="layout_style">end</property>
         <child>
+          <object class="GtkToggleButton" id="status_diff_button">
+            <property name="label" translatable="yes">Show Diff</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkButton" id="select_all_button">
             <property name="label">gtk-select-all</property>
             <property name="visible">True</property>
@@ -3745,7 +3760,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">0</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -3759,7 +3774,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <child>
@@ -3773,7 +3788,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">2</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
diff --git a/plugins/git/git-diff-command.c b/plugins/git/git-diff-command.c
index 498b1a7..14f5446 100644
--- a/plugins/git/git-diff-command.c
+++ b/plugins/git/git-diff-command.c
@@ -26,22 +26,45 @@
 
 G_DEFINE_TYPE (GitDiffCommand, git_diff_command, GIT_TYPE_RAW_OUTPUT_COMMAND);
 
+struct _GitDiffCommandPriv
+{
+       gchar *path;
+       GitDiffType type;
+};
+
 static void
 git_diff_command_init (GitDiffCommand *self)
 {
-
+       self->priv = g_new0 (GitDiffCommandPriv, 1);
 }
 
 static void
 git_diff_command_finalize (GObject *object)
 {
+       GitDiffCommand *self;
+
+       self = GIT_DIFF_COMMAND (object);
+
+       g_free (self->priv->path);
+       g_free (self->priv);
+
        G_OBJECT_CLASS (git_diff_command_parent_class)->finalize (object);
 }
 
 static guint
 git_diff_command_run (AnjutaCommand *command)
 {      
+       GitDiffCommand *self;
+
+       self = GIT_DIFF_COMMAND (command);
+
        git_command_add_arg (GIT_COMMAND (command), "diff");
+
+       if (self->priv->type == GIT_DIFF_INDEX)
+               git_command_add_arg (GIT_COMMAND (command), "--cached");
+
+       if (self->priv->path)
+               git_command_add_arg (GIT_COMMAND (command), self->priv->path);
        
        return 0;
 }
@@ -58,9 +81,17 @@ git_diff_command_class_init (GitDiffCommandClass *klass)
 
 
 GitDiffCommand *
-git_diff_command_new (const gchar *working_directory)
+git_diff_command_new (const gchar *working_directory, const gchar *path, 
+                      GitDiffType type)
 {
-       return g_object_new (GIT_TYPE_DIFF_COMMAND, 
+       GitDiffCommand *self;
+
+       self = g_object_new (GIT_TYPE_DIFF_COMMAND, 
                                                 "working-directory", working_directory,
                                                 NULL);
+
+       self->priv->path = g_strdup (path);
+       self->priv->type = type;
+
+       return self;
 }
diff --git a/plugins/git/git-diff-command.h b/plugins/git/git-diff-command.h
index b96f06d..a9bc440 100644
--- a/plugins/git/git-diff-command.h
+++ b/plugins/git/git-diff-command.h
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
 
 typedef struct _GitDiffCommandClass GitDiffCommandClass;
 typedef struct _GitDiffCommand GitDiffCommand;
+typedef struct _GitDiffCommandPriv GitDiffCommandPriv;
 
 struct _GitDiffCommandClass
 {
@@ -48,10 +49,19 @@ struct _GitDiffCommandClass
 struct _GitDiffCommand
 {
        GitRawOutputCommand parent_instance;
+
+       GitDiffCommandPriv *priv;
 };
 
+typedef enum
+{
+       GIT_DIFF_WORKING_TREE,
+       GIT_DIFF_INDEX
+} GitDiffType;
+
 GType git_diff_command_get_type (void) G_GNUC_CONST;
-GitDiffCommand *git_diff_command_new (const gchar *working_directory);
+GitDiffCommand *git_diff_command_new (const gchar *working_directory, 
+                                      const gchar *path, GitDiffType type);
 
 G_END_DECLS
 
diff --git a/plugins/git/git-diff-pane.c b/plugins/git/git-diff-pane.c
index dd67cd5..3a58f69 100644
--- a/plugins/git/git-diff-pane.c
+++ b/plugins/git/git-diff-pane.c
@@ -20,37 +20,6 @@
 #include "git-diff-pane.h"
 
 void
-on_diff_button_clicked (GtkAction *action, Git *plugin)
-{
-       IAnjutaDocumentManager *document_manager;
-       IAnjutaEditor *editor;
-       GitDiffCommand *diff_command;
-
-       document_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
-                                                                                                  
IAnjutaDocumentManager,
-                                                                                                  NULL);
-       editor = ianjuta_document_manager_add_buffer (document_manager,/* Translators: default file name for 
git diff's output */
-                                                                                                 
_("Uncommitted Changes.diff"),
-                                                                                                 "", NULL);
-
-       diff_command = git_diff_command_new (plugin->project_root_directory);
-
-       g_signal_connect (G_OBJECT (diff_command), "data-arrived",
-                                         G_CALLBACK (git_pane_send_raw_output_to_editor),
-                                         editor);
-
-       g_signal_connect (G_OBJECT (diff_command), "command-finished",
-                                         G_CALLBACK (git_pane_report_errors),
-                                         plugin);
-
-       g_signal_connect (G_OBJECT (diff_command), "command-finished",
-                                         G_CALLBACK (g_object_unref),
-                                         NULL);
-
-       anjuta_command_start (ANJUTA_COMMAND (diff_command));
-}
-
-void
 on_commit_diff_button_clicked (GtkAction *action, Git *plugin)
 {
        GitRevision *revision;
diff --git a/plugins/git/git-status-pane.c b/plugins/git/git-status-pane.c
index 6f74de7..5142abf 100644
--- a/plugins/git/git-status-pane.c
+++ b/plugins/git/git-status-pane.c
@@ -24,6 +24,7 @@ enum
        COL_SELECTED,
        COL_STATUS,
        COL_PATH,
+       COL_DIFF,
        COL_TYPE
 };
 
@@ -60,12 +61,14 @@ struct _GitStatusPanePriv
 
        /* 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;
-       GtkTreeIter not_updated_iter;
+       GtkTreePath *commit_section;
+       GtkTreePath *not_updated_section;
 
        /* Hash tables that show which items are selected in each section */
        GHashTable *selected_commit_items;
        GHashTable *selected_not_updated_items;
+
+       gboolean show_diff;
 };
 
 G_DEFINE_TYPE (GitStatusPane, git_status_pane, GIT_TYPE_PANE);
@@ -84,7 +87,7 @@ selected_renderer_data_func (GtkTreeViewColumn *tree_column,
         * Changeed but not updated. */
        gtk_cell_renderer_set_visible (renderer, 
                                       gtk_tree_store_iter_depth (GTK_TREE_STORE (model), 
-                                                                 iter) > 0);
+                                                                 iter) == 1);
 
        gtk_tree_model_get (model, iter, COL_SELECTED, &selected, -1);
 
@@ -105,7 +108,7 @@ status_icon_renderer_data_func (GtkTreeViewColumn *tree_column,
        /* Don't show this renderer on placeholders */
        gtk_cell_renderer_set_visible (renderer, 
                                       gtk_tree_store_iter_depth (GTK_TREE_STORE (model), 
-                                                                 iter) > 0);
+                                                                 iter) == 1);
 
        gtk_tree_model_get (model, iter, COL_STATUS, &status, -1);
 
@@ -167,7 +170,7 @@ status_name_renderer_data_func (GtkTreeViewColumn *tree_column,
        /* Don't show this renderer on placeholders */
        gtk_cell_renderer_set_visible (renderer, 
                                       gtk_tree_store_iter_depth (GTK_TREE_STORE (model), 
-                                                                 iter) > 0);
+                                                                 iter) == 1);
 
        switch (status)
        {
@@ -220,6 +223,11 @@ path_renderer_data_func (GtkTreeViewColumn *tree_column,
 
        gtk_tree_model_get (model, iter, COL_PATH, &path, -1);
 
+       /* Don't show this column on diffs */
+       gtk_cell_renderer_set_visible (renderer,
+                                      gtk_tree_store_iter_depth (GTK_TREE_STORE (model),
+                                                                 iter)  != 2);
+
        /* Use the path column to show placeholders as well */
        if (gtk_tree_store_iter_depth (GTK_TREE_STORE (model), iter) == 0)
        {
@@ -302,13 +310,59 @@ on_selected_renderer_toggled (GtkCellRendererToggle *renderer, gchar *tree_path,
 }
 
 static void
+on_diff_command_finished (AnjutaCommand *command, guint return_code, 
+                          gpointer data)
+{
+       GtkTreeModel *status_model;
+       GtkTreePath *parent_path;
+       GtkTreeIter parent_iter;
+       GtkTreeIter iter;
+       GString *string;
+       GQueue *output;
+       gchar *output_line;
+       GtkTreeView *status_view;
+
+       if (return_code == 0)
+       {
+               status_model = g_object_get_data (G_OBJECT (command), "model");
+               parent_path = g_object_get_data (G_OBJECT (command), "parent-path");
+               gtk_tree_model_get_iter (status_model, &parent_iter, parent_path);
+               string = g_string_new ("");
+               output = git_raw_output_command_get_output (GIT_RAW_OUTPUT_COMMAND (command));
+
+               while (g_queue_peek_head (output))
+               {
+                       output_line = g_queue_pop_head (output);
+                       g_string_append (string, output_line);
+
+                       g_free (output_line);
+               }
+
+               gtk_tree_store_append (GTK_TREE_STORE (status_model), &iter, &parent_iter);
+               gtk_tree_store_set (GTK_TREE_STORE (status_model), &iter, COL_DIFF, string->str, -1);
+
+               if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (command), "show-diff")))
+               {
+                       status_view = g_object_get_data (G_OBJECT (command), "status-view");
+                       gtk_tree_view_expand_row (status_view, parent_path, FALSE);
+               }
+
+               g_string_free (string, TRUE);
+       }
+}
+
+static void
 add_status_items (GQueue *output, GtkTreeStore *status_model, 
-                  GtkTreeIter *parent_iter, StatusType type)
+                  GtkTreeView *status_view, GtkTreePath *parent, 
+                  StatusType type, const gchar *working_directory, 
+                  gboolean show_diff)
 {
        GitStatus *status_object;
        AnjutaVcsStatus status;
        gchar *path;
+       GtkTreeIter parent_iter;
        GtkTreeIter iter;
+       GitDiffCommand *diff_command;
 
        while (g_queue_peek_head (output))
        {
@@ -316,7 +370,9 @@ add_status_items (GQueue *output, GtkTreeStore *status_model,
                status = git_status_get_vcs_status (status_object);
                path = git_status_get_path (status_object);
 
-               gtk_tree_store_append (status_model, &iter, parent_iter);
+               gtk_tree_model_get_iter (GTK_TREE_MODEL (status_model), &parent_iter, 
+                                        parent);
+               gtk_tree_store_append (status_model, &iter, &parent_iter);
                gtk_tree_store_set (status_model, &iter,
                                    COL_SELECTED, FALSE,
                                    COL_STATUS, status,
@@ -324,8 +380,30 @@ add_status_items (GQueue *output, GtkTreeStore *status_model,
                                    COL_TYPE, type,
                                    -1);
 
+               diff_command = git_diff_command_new (working_directory, path,
+                                                    type == STATUS_TYPE_NOT_UPDATED ? GIT_DIFF_WORKING_TREE 
: GIT_DIFF_INDEX);
+               
+               g_signal_connect (G_OBJECT (diff_command), "command-finished",
+                                 G_CALLBACK (on_diff_command_finished),
+                                 NULL);
+
+               g_signal_connect (G_OBJECT (diff_command), "command-finished",
+                                 G_CALLBACK (g_object_unref),
+                                 NULL);
+
+               g_object_set_data_full (G_OBJECT (diff_command), "parent-path", 
+                                       gtk_tree_model_get_path (GTK_TREE_MODEL (status_model), 
+                                                                &iter),
+                                       (GDestroyNotify) gtk_tree_path_free);
+               g_object_set_data (G_OBJECT (diff_command), "model", status_model);
+               g_object_set_data (G_OBJECT (diff_command), "status-view", status_view);
+               g_object_set_data (G_OBJECT (diff_command), "show-diff", 
+                                  GINT_TO_POINTER (show_diff));
+               
                g_free (path);
                g_object_unref (status_object);
+
+               anjuta_command_start (ANJUTA_COMMAND (diff_command));
        }
 }
 
@@ -334,15 +412,23 @@ on_commit_status_data_arrived (AnjutaCommand *command,
                                GitStatusPane *self)
 {
        GtkTreeStore *status_model;
+       GtkTreeView *status_view;
        GQueue *output;
+       gchar *working_directory;
 
        status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
                                                               "status_model"));
+       status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                            "status_view"));
        output = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
+       g_object_get (G_OBJECT (command), "working-directory", &working_directory, 
+                     NULL);
 
-       add_status_items (output, status_model, &(self->priv->commit_iter),
-                         STATUS_TYPE_COMMIT);
+       add_status_items (output, status_model, status_view, 
+                         self->priv->commit_section, STATUS_TYPE_COMMIT,
+                         working_directory, self->priv->show_diff);
 
+       g_free (working_directory);
 }
 
 static void
@@ -350,44 +436,60 @@ on_not_updated_status_data_arrived (AnjutaCommand *command,
                                     GitStatusPane *self)
 {
        GtkTreeStore *status_model;
+       GtkTreeView *status_view;
        GQueue *output;
+       gchar *working_directory;
 
        status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
                                                               "status_model"));
+       status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                            "status_view"));
        output = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
+       g_object_get (G_OBJECT (command), "working-directory", &working_directory, 
+                     NULL);
+
+       add_status_items (output, status_model, status_view, 
+                         self->priv->not_updated_section, STATUS_TYPE_NOT_UPDATED, 
+                         working_directory, self->priv->show_diff);
 
-       add_status_items (output, status_model, &(self->priv->not_updated_iter),
-                         STATUS_TYPE_NOT_UPDATED);
+       g_free (working_directory);
 }
 
 static void
 git_status_pane_clear (GitStatusPane *self)
 {
        GtkTreeStore *status_model;
+       GtkTreeIter iter;
 
        status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,     
                                                               "status_model"));
 
        /* Clear any existing model data and create the placeholders */
        gtk_tree_store_clear (status_model);
+
+       gtk_tree_path_free (self->priv->commit_section);
+       gtk_tree_path_free (self->priv->not_updated_section);
        
-       gtk_tree_store_append (status_model, &(self->priv->commit_iter), NULL);
-       gtk_tree_store_set (status_model, &(self->priv->commit_iter), 
+       gtk_tree_store_append (status_model, &iter, NULL);
+       gtk_tree_store_set (status_model, &iter, 
                            COL_PATH, _("Changes to be committed"), 
                            COL_SELECTED, FALSE,
                            COL_STATUS, ANJUTA_VCS_STATUS_NONE,
                            COL_TYPE, STATUS_TYPE_NONE,
                            -1);
+       
+       self->priv->commit_section = gtk_tree_model_get_path (GTK_TREE_MODEL (status_model), &iter);
 
-       gtk_tree_store_append (status_model, &(self->priv->not_updated_iter), 
-                              NULL);
-       gtk_tree_store_set (status_model, &(self->priv->not_updated_iter), 
+       gtk_tree_store_append (status_model, &iter, NULL);
+       gtk_tree_store_set (status_model, &iter, 
                            COL_PATH, _("Changed but not updated"), 
                            COL_SELECTED, FALSE, 
                            COL_STATUS, ANJUTA_VCS_STATUS_NONE,
                            COL_TYPE, STATUS_TYPE_NONE,
                            -1);
 
+       self->priv->not_updated_section = gtk_tree_model_get_path (GTK_TREE_MODEL (status_model), &iter);
+
        g_hash_table_remove_all (self->priv->selected_commit_items);
        g_hash_table_remove_all (self->priv->selected_not_updated_items);
 }
@@ -398,7 +500,8 @@ git_status_pane_set_selected_column_state (GitStatusPane *self,
                                            gboolean state)
 {
        GtkTreeModel *status_model;
-       GtkTreeIter *parent_iter;
+       GtkTreePath *section;
+       GtkTreeIter parent_iter;
        gint i;
        GtkTreeIter iter;
        gchar *path;
@@ -406,22 +509,25 @@ git_status_pane_set_selected_column_state (GitStatusPane *self,
 
        status_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
                                                               "status_model"));
+
        switch (type)
        {
                case STATUS_TYPE_COMMIT:
-                       parent_iter = &(self->priv->commit_iter);
+                       section = self->priv->commit_section;
                        break;
                case STATUS_TYPE_NOT_UPDATED:
-                       parent_iter = &(self->priv->not_updated_iter);
+                       section = self->priv->not_updated_section;
                        break;
                default:
                        return;
                        break;
        }
+
+       gtk_tree_model_get_iter (status_model, &parent_iter, section);
        
        i = 0;
 
-       while (gtk_tree_model_iter_nth_child (status_model, &iter, parent_iter,
+       while (gtk_tree_model_iter_nth_child (status_model, &iter, &parent_iter,
                                              i++))
        {
                gtk_tree_store_set (GTK_TREE_STORE (status_model), &iter, 
@@ -544,24 +650,32 @@ on_status_view_button_press_event (GtkWidget *widget, GdkEvent *event,
        AnjutaPlugin *plugin;
        AnjutaUI *ui;
        GtkTreeView *status_view;
-       GtkTreeSelection *selection;
+       GtkTreePath *path;
+       gboolean path_valid;
        GtkTreeModel *status_model;
        GtkTreeIter iter;
        StatusType status_type;
        GtkMenu *menu;
+       gboolean ret = FALSE;;
 
        button_event = (GdkEventButton *) event;
+       status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                            "status_view"));
+       status_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
+                                                              "status_model"));
+       path_valid = gtk_tree_view_get_path_at_pos (status_view, 
+                                                   button_event->x, button_event->y,
+                                                               &path, NULL, NULL, NULL);
        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))
+               if (path_valid && gtk_tree_model_get_iter (status_model, &iter, path))
                {
                        gtk_tree_model_get (status_model, &iter, COL_TYPE, &status_type, 
                                            -1);
@@ -585,10 +699,70 @@ on_status_view_button_press_event (GtkWidget *widget, GdkEvent *event,
                }
        }
 
-       return FALSE;
+       if (path_valid)
+       {
+               /* Don't forward key events to diff columns */
+               ret = gtk_tree_path_get_depth (path) == 3;
+
+               gtk_tree_path_free (path);
+       }
+
+       return ret;
+}
+
+static gboolean
+on_status_view_row_selected (GtkTreeSelection *selection, 
+                             GtkTreeModel *model,
+                             GtkTreePath *path,
+                             gboolean path_currently_selected,
+                             gpointer user_data)
+{
+       return gtk_tree_path_get_depth (path) == 2;
+}
+
+static void 
+git_status_pane_expand_placeholders_full (GitStatusPane *self, 
+                                          gboolean open_all)
+{
+       GtkTreeView *status_view;
+
+       if (self->priv->commit_section && self->priv->not_updated_section)
+       {
+               status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                                    "status_view"));
+
+               gtk_tree_view_expand_row (status_view, self->priv->commit_section, 
+                                         open_all);
+               gtk_tree_view_expand_row (status_view, self->priv->not_updated_section, 
+                                         open_all);
+       }
+}
+
+static void
+git_status_pane_expand_placeholders (GitStatusPane *self)
+{
+       git_status_pane_expand_placeholders_full (self, FALSE);
 }
 
 static void
+on_status_diff_button_toggled (GtkToggleButton *button, GitStatusPane *self)
+{
+       GtkTreeView *status_view;
+
+       self->priv->show_diff = gtk_toggle_button_get_active (button);
+
+       if (!self->priv->show_diff)
+       {
+               status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+                                                                    "status_view"));
+
+               gtk_tree_view_collapse_all (status_view);
+       }
+
+       git_status_pane_expand_placeholders_full (self, self->priv->show_diff);
+}                                 
+
+static void
 git_status_pane_init (GitStatusPane *self)
 {
        gchar *objects[] = {"status_pane",
@@ -601,6 +775,9 @@ git_status_pane_init (GitStatusPane *self)
        GtkCellRenderer *status_icon_renderer;
        GtkCellRenderer *status_name_renderer;
        GtkCellRenderer *path_renderer;
+       GtkCellRenderer *diff_renderer;
+       GtkTreeSelection *selection;
+       GtkWidget *status_diff_button;
        GtkWidget *refresh_button;
        GtkWidget *select_all_button;
        GtkWidget *clear_button;
@@ -636,6 +813,9 @@ git_status_pane_init (GitStatusPane *self)
                                                                          "status_name_renderer"));
        path_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
                                                                   "path_renderer"));
+       diff_renderer = anjuta_cell_renderer_diff_new ();
+       status_diff_button = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
+                                                                "status_diff_button"));
        refresh_button = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
                                                             "refresh_button"));
        select_all_button = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
@@ -659,10 +839,24 @@ git_status_pane_init (GitStatusPane *self)
                                                 (GtkTreeCellDataFunc) path_renderer_data_func,
                                                 NULL, NULL);
 
+       gtk_tree_view_column_pack_start (status_column, diff_renderer, TRUE);
+       gtk_tree_view_column_add_attribute (status_column, diff_renderer, "diff", COL_DIFF);
+       
        g_signal_connect (G_OBJECT (selected_renderer), "toggled",
                          G_CALLBACK (on_selected_renderer_toggled),
                          self);
 
+       g_signal_connect (G_OBJECT (status_diff_button), "toggled",
+                         G_CALLBACK (on_status_diff_button_toggled),
+                         self);
+
+       /* Don't allow the user to select any row that doesn't have a path,
+        * such as the placeholders or diff rows */
+       selection = gtk_tree_view_get_selection (status_view);
+       gtk_tree_selection_set_select_function (selection, 
+                                               on_status_view_row_selected,
+                                               NULL, NULL);
+
        g_signal_connect_swapped (G_OBJECT (refresh_button), "clicked",
                                  G_CALLBACK (anjuta_dock_pane_refresh),
                                  self);
@@ -704,6 +898,8 @@ git_status_pane_finalize (GObject *object)
        self = GIT_STATUS_PANE (object);
 
        g_object_unref (self->priv->builder);
+       gtk_tree_path_free (self->priv->commit_section);
+       gtk_tree_path_free (self->priv->not_updated_section);
        g_hash_table_destroy (self->priv->selected_commit_items);
        g_hash_table_destroy (self->priv->selected_not_updated_items);
        g_free (self->priv);
@@ -748,23 +944,21 @@ AnjutaDockPane *
 git_status_pane_new (Git *plugin)
 {
        GitStatusPane *self;
-       GtkTreeView *status_view;
+       GObject *status_diff_button;
 
        self = g_object_new (GIT_TYPE_STATUS_PANE, "plugin", plugin, NULL);
-       status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
-                                                                                                             
   "status_view"));
+       status_diff_button = gtk_builder_get_object (self->priv->builder, 
+                                                    "status_diff_button");
 
        g_signal_connect_swapped (G_OBJECT (plugin->commit_status_command), 
                                  "command-started",
                                  G_CALLBACK (git_status_pane_clear),
                                  self);
 
-       /* Expand the placeholders so something is visible to the user after 
-        * refreshing */
        g_signal_connect_swapped (G_OBJECT (plugin->not_updated_status_command),
                                  "command-finished",
-                                 G_CALLBACK (gtk_tree_view_expand_all),
-                                 status_view);
+                                 G_CALLBACK (git_status_pane_expand_placeholders),
+                                 self);
 
        g_signal_connect (G_OBJECT (plugin->commit_status_command),
                          "data-arrived",
@@ -776,6 +970,9 @@ git_status_pane_new (Git *plugin)
                          G_CALLBACK (on_not_updated_status_data_arrived),
                          self);
 
+       g_settings_bind (plugin->settings, "show-status-diff",
+                        status_diff_button, "active", G_SETTINGS_BIND_DEFAULT);
+
        return ANJUTA_DOCK_PANE (self);
 }
 
diff --git a/plugins/git/git-status-pane.h b/plugins/git/git-status-pane.h
index c8eeaf0..e5d6c72 100644
--- a/plugins/git/git-status-pane.h
+++ b/plugins/git/git-status-pane.h
@@ -21,9 +21,11 @@
 #define _GIT_STATUS_PANE_H_
 
 #include <glib-object.h>
+#include <libanjuta/anjuta-cell-renderer-diff.h>
 #include "git-pane.h"
 #include "git-status-command.h"
 #include "git-add-command.h"
+#include "git-diff-command.h"
 
 G_BEGIN_DECLS
 
diff --git a/plugins/git/git-vcs-interface.c b/plugins/git/git-vcs-interface.c
index 5f1eca5..d1d7cb4 100644
--- a/plugins/git/git-vcs-interface.c
+++ b/plugins/git/git-vcs-interface.c
@@ -150,7 +150,7 @@ git_ivcs_diff (IAnjutaVcs *obj, GFile* file,
        
        if (project_root_directory)
        {
-               diff_command = git_diff_command_new (project_root_directory);
+               diff_command = git_diff_command_new (project_root_directory, NULL, GIT_DIFF_WORKING_TREE);
                
                g_object_set_data_full (G_OBJECT (diff_command), "file", 
                                        g_object_ref (file),
diff --git a/plugins/git/org.gnome.anjuta.plugins.git.gschema.xml.in 
b/plugins/git/org.gnome.anjuta.plugins.git.gschema.xml.in
index c55883f..e2056dc 100644
--- a/plugins/git/org.gnome.anjuta.plugins.git.gschema.xml.in
+++ b/plugins/git/org.gnome.anjuta.plugins.git.gschema.xml.in
@@ -2,6 +2,9 @@
     <schema id="org.gnome.anjuta.plugins.git" path="/org/gnome/anjuta/plugins/git/">
         <key name="show-command-bar" type="b">
             <default>true</default>        
-        </key>    
+        </key>
+               <key name = "show-status-diff" type="b">
+                       <default>false</default>
+               </key>    
     </schema>
 </schemalist>
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index 819707c..9ef9be3 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -152,14 +152,6 @@ AnjutaCommandBarEntry status_entries[] =
                G_CALLBACK (on_commit_button_clicked)
        },
        {
-               ANJUTA_COMMAND_BAR_ENTRY_BUTTON,
-               "Diff",
-               N_("Diff uncommitted changes"),
-               N_("Show a diff of uncommitted changes in an editor"),
-               GTK_STOCK_ZOOM_100,
-               G_CALLBACK (on_diff_button_clicked)
-       },
-       {
                ANJUTA_COMMAND_BAR_ENTRY_FRAME,
                "NULL",
                N_("Files"),


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