[gitg/wip/submodules: 5/5] Add basic history view for staged/unstaged submodules



commit 0618918604eb004ed537878d4d9c0c4d65f36c9b
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sat Dec 13 17:27:46 2014 +0100

    Add basic history view for staged/unstaged submodules

 gitg/Makefile.am                                   |    1 +
 gitg/commit/gitg-commit-paned.vala                 |    8 +
 .../commit/gitg-commit-submodule-history-view.vala |   43 +++++
 gitg/commit/gitg-commit.vala                       |  199 ++++++++++++++++++-
 gitg/resources/gitg-resources.xml                  |    1 +
 gitg/resources/ui/gitg-commit-paned.ui             |   11 +-
 .../ui/gitg-commit-submodule-history-view.ui       |   82 ++++++++
 7 files changed, 329 insertions(+), 16 deletions(-)
---
diff --git a/gitg/Makefile.am b/gitg/Makefile.am
index 9014446..ad115a3 100644
--- a/gitg/Makefile.am
+++ b/gitg/Makefile.am
@@ -78,6 +78,7 @@ gitg_gitg_VALASOURCES =                                               \
        gitg/commit/gitg-commit.vala                            \
        gitg/commit/gitg-commit-paned.vala                      \
        gitg/commit/gitg-commit-sidebar.vala                    \
+       gitg/commit/gitg-commit-submodule-history-view.vala     \
        gitg/commit/gitg-commit-submodule-diff-view.vala        \
        gitg/commit/gitg-commit-submodule-info.vala             \
        gitg/commit/gitg-commit-dialog.vala                     \
diff --git a/gitg/commit/gitg-commit-paned.vala b/gitg/commit/gitg-commit-paned.vala
index 10f8bad..c19cb54 100644
--- a/gitg/commit/gitg-commit-paned.vala
+++ b/gitg/commit/gitg-commit-paned.vala
@@ -29,6 +29,9 @@ class Paned : Gtk.Paned
        [GtkChild (name = "diff_view")]
        private Gitg.DiffView d_diff_view;
 
+       [GtkChild (name = "submodule_history_view")]
+       private SubmoduleHistoryView d_submodule_history_view;
+
        [GtkChild (name = "submodule_diff_view")]
        private SubmoduleDiffView d_submodule_diff_view;
 
@@ -54,6 +57,11 @@ class Paned : Gtk.Paned
                get { return d_diff_view; }
        }
 
+       public SubmoduleHistoryView submodule_history_view
+       {
+               get { return d_submodule_history_view; }
+       }
+
        public SubmoduleDiffView submodule_diff_view
        {
                get { return d_submodule_diff_view; }
diff --git a/gitg/commit/gitg-commit-submodule-history-view.vala 
b/gitg/commit/gitg-commit-submodule-history-view.vala
new file mode 100644
index 0000000..bcea384
--- /dev/null
+++ b/gitg/commit/gitg-commit-submodule-history-view.vala
@@ -0,0 +1,43 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2014 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace GitgCommit
+{
+
+[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-commit-submodule-history-view.ui")]
+class SubmoduleHistoryView : Gtk.Paned
+{
+  [GtkChild (name = "commit_list_view")]
+  private Gitg.CommitListView d_commit_list_view;
+
+  [GtkChild (name = "diff_view")]
+  private Gitg.DiffView d_diff_view;
+
+  public Gitg.CommitListView commit_list_view
+  {
+    get { return d_commit_list_view; }
+  }
+
+  public Gitg.DiffView diff_view
+  {
+    get { return d_diff_view; }
+  }
+}
+
+}
\ No newline at end of file
diff --git a/gitg/commit/gitg-commit.vala b/gitg/commit/gitg-commit.vala
index 5226729..0dd084f 100644
--- a/gitg/commit/gitg-commit.vala
+++ b/gitg/commit/gitg-commit.vala
@@ -27,6 +27,19 @@ namespace GitgCommit
                private bool d_reloading;
                private bool d_has_staged;
 
+               private enum UiType
+               {
+                       DIFF,
+                       SUBMODULE_HISTORY,
+                       SUBMODULE_DIFF
+               }
+
+               private enum IndexType
+               {
+                       STAGED,
+                       UNSTAGED
+               }
+
                public GitgExt.Application? application { owned get; construct set; }
 
                public Activity(GitgExt.Application application)
@@ -91,11 +104,21 @@ namespace GitgCommit
 
                private delegate void UpdateDiffCallback();
                private UpdateDiffCallback? d_update_diff_callback;
+               private bool d_submodule_history_select_first;
+               private Ggit.Submodule? d_current_submodule;
+               private Gitg.Repository? d_current_submodule_repository;
 
                private void show_unstaged_diff(Gitg.StageStatusItem[] items)
                {
-                       show_submodule_ui(false);
-                       show_unstaged_diff_intern(application.repository, d_main.diff_view, items, true);
+                       if (items.length == 1 && items[0] is Gitg.StageStatusSubmodule)
+                       {
+                               show_submodule_history((Gitg.StageStatusSubmodule)items[0], 
IndexType.UNSTAGED);
+                       }
+                       else
+                       {
+                               show_ui(UiType.DIFF);
+                               show_unstaged_diff_intern(application.repository, d_main.diff_view, items, 
true);
+                       }
                }
 
                private void show_unstaged_diff_intern(Gitg.Repository         repository,
@@ -179,16 +202,18 @@ namespace GitgCommit
                        reload();
                }
 
-               private void show_submodule_ui(bool show)
+               private void show_ui(UiType type)
                {
-                       d_main.submodule_diff_view.set_visible(show);
-                       d_main.diff_view.set_visible(!show);
+                       d_main.submodule_history_view.set_visible(type == UiType.SUBMODULE_HISTORY);
+                       d_main.submodule_diff_view.set_visible(type == UiType.SUBMODULE_DIFF);
+                       d_main.diff_view.set_visible(type == UiType.DIFF);
 
-                       if (show)
+                       if (type != UiType.DIFF)
                        {
                                d_main.diff_view.diff = null;
                        }
-                       else
+
+                       if (type != UiType.SUBMODULE_DIFF)
                        {
                                var view = d_main.submodule_diff_view;
 
@@ -196,6 +221,21 @@ namespace GitgCommit
                                view.diff_view_staged.diff = null;
                                view.diff_view_unstaged.diff = null;
                        }
+
+                       if (type != UiType.SUBMODULE_HISTORY)
+                       {
+                               var view = d_main.submodule_history_view;
+                               var model = ((Gitg.CommitModel)view.commit_list_view.model);
+
+                               if (model != null)
+                               {
+                                       model.repository = null;
+                               }
+
+                               view.diff_view.diff = null;
+                               d_current_submodule = null;
+                               d_current_submodule_repository = null;
+                       }
                }
 
                private void on_unstaged_activated(Gitg.StageStatusItem[] items)
@@ -207,7 +247,7 @@ namespace GitgCommit
 
                private void show_submodule_diff(Gitg.StageStatusSubmodule sub)
                {
-                       show_submodule_ui(true);
+                       show_ui(UiType.SUBMODULE_DIFF);
 
                        var view = d_main.submodule_diff_view;
 
@@ -231,6 +271,110 @@ namespace GitgCommit
                        show_unstaged_diff_intern(repo, view.diff_view_unstaged, null, false);
                }
 
+               private void submodule_history_selection_changed(Gitg.Commit? commit)
+               {
+                       var view = d_main.submodule_history_view;
+
+                       if (commit == null)
+                       {
+                               view.diff_view.diff = null;
+                               return;
+                       }
+
+                       if (d_current_submodule_repository == null)
+                       {
+                               return;
+                       }
+
+                       var repo = d_current_submodule_repository;
+
+                       var commit_tree = commit.get_tree();
+
+                       var head = d_current_submodule.get_head_id();
+                       Ggit.Commit head_commit;
+
+                       try
+                       {
+                               head_commit = repo.lookup<Gitg.Commit>(head);
+                       }
+                       catch (Error e)
+                       {
+                               // TODO: show error to user
+                               stderr.printf("Failed to get head commit: %s\n", e.message);
+                               return;
+                       }
+
+                       var head_tree = head_commit.get_tree();
+
+                       Ggit.Diff diff;
+
+                       try
+                       {
+                               diff = new Ggit.Diff.tree_to_tree(repo, head_tree, commit_tree, 
view.diff_view.options);
+                       }
+                       catch (Error e)
+                       {
+                               // TODO: show error to user
+                               stderr.printf("Failed to get diff: %s\n", e.message);
+                               return;
+                       }
+
+                       view.diff_view.diff = diff;
+               }
+
+               private void show_submodule_history(Gitg.StageStatusSubmodule sub,
+                                                   IndexType                 type)
+               {
+                       show_ui(UiType.SUBMODULE_HISTORY);
+
+                       d_current_submodule = null;
+                       d_current_submodule_repository = null;
+
+                       Gitg.Repository repo;
+                       var submodule = sub.submodule;
+
+                       try
+                       {
+                               repo = submodule.open() as Gitg.Repository;
+                       }
+                       catch (Error e)
+                       {
+                               // TODO: show to user
+                               stderr.printf("Failed to open submodule repository: %s\n", e.message);
+                               return;
+                       }
+
+                       d_current_submodule = submodule;
+                       d_current_submodule_repository = repo;
+
+                       var view = d_main.submodule_history_view;
+                       var model = (Gitg.CommitModel)view.commit_list_view.model;
+
+                       if (model == null)
+                       {
+                               model = new Gitg.CommitModel(repo);
+                               view.commit_list_view.model = model;
+                       }
+                       else
+                       {
+                               model.repository = repo;
+                       }
+
+                       if (type == IndexType.STAGED)
+                       {
+                               model.set_include(new Ggit.OId[] { submodule.get_index_id() });
+                               model.set_exclude(new Ggit.OId[] { submodule.get_head_id() });
+                       }
+                       else
+                       {
+                               model.set_include(new Ggit.OId[] { submodule.get_workdir_id() });
+                               model.set_exclude(new Ggit.OId[] { submodule.get_index_id() });
+                       }
+
+                       d_submodule_history_select_first = true;
+                       model.reload();
+               }
+
                private void show_staged_diff_intern(Gitg.Repository         repository,
                                                     Gitg.DiffView           view,
                                                     Gitg.StageStatusItem[]? items,
@@ -266,8 +410,15 @@ namespace GitgCommit
 
                private void show_staged_diff(Gitg.StageStatusItem[] items)
                {
-                       show_submodule_ui(false);
-                       show_staged_diff_intern(application.repository, d_main.diff_view, items, true);
+                       if (items.length == 1 && items[0] is Gitg.StageStatusSubmodule)
+                       {
+                               show_submodule_history((Gitg.StageStatusSubmodule)items[0], IndexType.STAGED);
+                       }
+                       else
+                       {
+                               show_ui(UiType.DIFF);
+                               show_staged_diff_intern(application.repository, d_main.diff_view, items, 
true);
+                       }
                }
 
                private async void unstage_items(owned Gitg.StageStatusItem[] items)
@@ -1183,7 +1334,7 @@ namespace GitgCommit
 
                        if (sitems.length == 0)
                        {
-                               show_submodule_ui(false);
+                               show_ui(UiType.DIFF);
                                d_main.diff_view.diff = null;
                                return;
                        }
@@ -1292,6 +1443,32 @@ namespace GitgCommit
 
                        d_main.sidebar.populate_popup.connect(do_populate_menu);
 
+                       var view = d_main.submodule_history_view.commit_list_view;
+                       var model = new Gitg.CommitModel(null);
+                       view.model = model;
+
+                       model.row_inserted.connect_after((model, path, iter) => {
+                               if (d_submodule_history_select_first)
+                               {
+                                       d_submodule_history_select_first = false;
+                                       view.get_selection().select_path(path);
+                               }
+                       });
+
+                       view.get_selection().changed.connect((selection) => {
+                               Gtk.TreeModel m;
+                               Gtk.TreeIter iter;
+
+                               if (selection.get_selected(out m, out iter))
+                               {
+                                       submodule_history_selection_changed(model.commit_from_iter(iter));
+                               }
+                               else
+                               {
+                                       submodule_history_selection_changed(null);
+                               }
+                       });
+
                        var settings = new Settings("org.gnome.gitg.preferences.commit.diff");
 
                        settings.bind("context-lines",
diff --git a/gitg/resources/gitg-resources.xml b/gitg/resources/gitg-resources.xml
index e04c14e..a20d66a 100644
--- a/gitg/resources/gitg-resources.xml
+++ b/gitg/resources/gitg-resources.xml
@@ -14,6 +14,7 @@
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-history-ref-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-history-ref-header.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-paned.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-submodule-history-view.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-submodule-diff-view.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-submodule-info.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-dialog.ui</file>
diff --git a/gitg/resources/ui/gitg-commit-paned.ui b/gitg/resources/ui/gitg-commit-paned.ui
index 902bf2e..34fd96a 100644
--- a/gitg/resources/ui/gitg-commit-paned.ui
+++ b/gitg/resources/ui/gitg-commit-paned.ui
@@ -49,6 +49,12 @@
           </object>
         </child>
         <child>
+          <object class="GitgCommitSubmoduleHistoryView" id="submodule_history_view">
+            <property name="visible">False</property>
+            <property name="can_focus">False</property>
+          </object>
+        </child>
+        <child>
           <object class="GitgCommitSubmoduleDiffView" id="submodule_diff_view">
             <property name="visible">False</property>
             <property name="can_focus">False</property>
@@ -57,11 +63,6 @@
             <property name="margin_top">12</property>
             <property name="margin_bottom">12</property>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkFrame" id="frame_commit">
diff --git a/gitg/resources/ui/gitg-commit-submodule-history-view.ui 
b/gitg/resources/ui/gitg-commit-submodule-history-view.ui
new file mode 100644
index 0000000..578f475
--- /dev/null
+++ b/gitg/resources/ui/gitg-commit-submodule-history-view.ui
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.3 -->
+  <!-- interface-requires gitg 3.0 -->
+  <template class="GitgCommitSubmoduleHistoryView" parent="GtkPaned">
+    <property name="orientation">vertical</property>
+    <property name="position">300</property>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolled_window_commit_list">
+        <property name="visible">True</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="can_focus">True</property>
+        <property name="shadow-type">none</property>
+        <child>
+          <object class="GitgCommitListView" id="commit_list_view">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="has_focus">True</property>
+            <property name="fixed-height-mode">True</property>
+            <property name="headers-visible">False</property>
+            <child>
+              <object class="GtkTreeViewColumn" id="column_commit_list_subject">
+                <property name="title" translatable="yes">Subject</property>
+                <property name="sizing">fixed</property>
+                <property name="resizable">True</property>
+                <property name="expand">True</property>
+                <property name="fixed-width">50</property>
+                <child>
+                  <object class="GitgCellRendererLanes" id="renderer_commit_list_subject">
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <attributes>
+                    <attribute name="text">1</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn" id="column_commit_list_author">
+                <property name="title" translatable="yes">Author</property>
+                <property name="sizing">fixed</property>
+                <property name="resizable">True</property>
+                <property name="fixed-width">180</property>
+                <child>
+                  <object class="GdStyledTextRenderer" id="renderer_commit_list_author">
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <attributes>
+                    <attribute name="text">4</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn" id="column_commit_list_author_date">
+                <property name="title" translatable="yes">Date</property>
+                <property name="sizing">fixed</property>
+                <property name="resizable">True</property>
+                <property name="fixed-width">150</property>
+                <child>
+                  <object class="GdStyledTextRenderer" id="renderer_commit_list_author_date">
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <attributes>
+                    <attribute name="text">6</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GitgDiffView" id="diff_view">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+      </object>
+    </child>
+  </template>
+</interface>
\ No newline at end of file


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