[gitg] Restore commit selection



commit 842a3312b9e56746969d2b26af2b7c64c36381d6
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Wed Jun 25 16:18:29 2014 +0200

    Restore commit selection

 gitg/commit/gitg-commit.vala      |  140 +++++++++++++++++++++++--------
 libgitg/gitg-sidebar.vala         |  169 ++++++++++++++++++++-----------------
 libgitg/resources/sidebar-view.ui |   15 +---
 3 files changed, 199 insertions(+), 125 deletions(-)
---
diff --git a/gitg/commit/gitg-commit.vala b/gitg/commit/gitg-commit.vala
index b404ce9..0e0f848 100644
--- a/gitg/commit/gitg-commit.vala
+++ b/gitg/commit/gitg-commit.vala
@@ -26,9 +26,55 @@ namespace GitgCommit
                private Paned? d_main;
                private bool d_reloading;
                private bool d_has_staged;
+               private Gitg.StageStatusFile? d_current_file;
+               private bool d_current_staged;
 
                public GitgExt.Application? application { owned get; construct set; }
 
+               private class SidebarFile : Object, Gitg.SidebarItem
+               {
+                       Gitg.StageStatusFile d_file;
+
+                       public SidebarFile(Gitg.StageStatusFile f)
+                       {
+                               d_file = f;
+                       }
+
+                       public string text
+                       {
+                               owned get { return d_file.path; }
+                       }
+
+                       private string? icon_for_status(Ggit.StatusFlags status)
+                       {
+                               if ((status & (Ggit.StatusFlags.INDEX_NEW |
+                                                  Ggit.StatusFlags.WORKING_TREE_NEW)) != 0)
+                               {
+                                       return "list-add-symbolic";
+                               }
+                               else if ((status & (Ggit.StatusFlags.INDEX_MODIFIED |
+                                                       Ggit.StatusFlags.INDEX_RENAMED |
+                                                       Ggit.StatusFlags.INDEX_TYPECHANGE |
+                                                       Ggit.StatusFlags.WORKING_TREE_MODIFIED |
+                                                       Ggit.StatusFlags.WORKING_TREE_TYPECHANGE)) != 0)
+                               {
+                                       return "text-editor-symbolic";
+                               }
+                               else if ((status & (Ggit.StatusFlags.INDEX_DELETED |
+                                                       Ggit.StatusFlags.WORKING_TREE_DELETED)) != 0)
+                               {
+                                       return "edit-delete-symbolic";
+                               }
+
+                               return null;
+                       }
+
+                       public string? icon_name
+                       {
+                               owned get { return icon_for_status(d_file.flags); }
+                       }
+               }
+
                public Activity(GitgExt.Application application)
                {
                        Object(application: application);
@@ -82,30 +128,6 @@ namespace GitgCommit
                        return action == "commit";
                }
 
-               private string? icon_for_status(Ggit.StatusFlags status)
-               {
-                       if ((status & (Ggit.StatusFlags.INDEX_NEW |
-                                      Ggit.StatusFlags.WORKING_TREE_NEW)) != 0)
-                       {
-                               return "list-add-symbolic";
-                       }
-                       else if ((status & (Ggit.StatusFlags.INDEX_MODIFIED |
-                                           Ggit.StatusFlags.INDEX_RENAMED |
-                                           Ggit.StatusFlags.INDEX_TYPECHANGE |
-                                           Ggit.StatusFlags.WORKING_TREE_MODIFIED |
-                                           Ggit.StatusFlags.WORKING_TREE_TYPECHANGE)) != 0)
-                       {
-                               return "text-editor-symbolic";
-                       }
-                       else if ((status & (Ggit.StatusFlags.INDEX_DELETED |
-                                           Ggit.StatusFlags.WORKING_TREE_DELETED)) != 0)
-                       {
-                               return "edit-delete-symbolic";
-                       }
-
-                       return null;
-               }
-
                private delegate void StageUnstageCallback(Gitg.StageStatusFile f, int numclick);
 
                private void show_unstaged_diff(Gitg.StageStatusFile f)
@@ -172,6 +194,9 @@ namespace GitgCommit
 
                private void on_unstaged_activated(Gitg.StageStatusFile f, int numclick)
                {
+                       d_current_file = f;
+                       d_current_staged = false;
+
                        if (numclick == 1)
                        {
                                show_unstaged_diff(f);
@@ -253,6 +278,9 @@ namespace GitgCommit
 
                private void on_staged_activated(Gitg.StageStatusFile f, int numclick)
                {
+                       d_current_file = f;
+                       d_current_staged = true;
+
                        if (numclick == 1)
                        {
                                show_staged_diff(f);
@@ -270,19 +298,30 @@ namespace GitgCommit
                        }
                }
 
-               private void append_files(Gitg.SidebarStore      model,
-                                         Gitg.StageStatusFile[] files,
-                                         StageUnstageCallback?  callback)
+               private SidebarFile? append_files(Gitg.SidebarStore      model,
+                                                 Gitg.StageStatusFile[] files,
+                                                 Gitg.StageStatusFile?  current,
+                                                 StageUnstageCallback?  callback)
                {
+                       SidebarFile? citem = null;
+       
                        foreach (var f in files)
                        {
-                               model.append_normal(f.path, null, icon_for_status(f.flags), (numclick) => {
-                                       if (callback != null)
-                                       {
-                                               callback(f, numclick);
-                                       }
+                               var item = new SidebarFile(f);
+
+                               if (current != null && f.path == current.path)
+                               {
+                                       citem = item;
+                               }
+
+                               item.activated.connect((numclick) => {
+                                       callback(f, numclick);
                                });
+
+                               model.append(item);
                        }
+
+                       return citem;
                }
 
                public void reload()
@@ -296,6 +335,9 @@ namespace GitgCommit
 
                        d_reloading = true;
 
+                       var currentfile = d_current_file;
+                       d_current_file = null;
+
                        // Preload author avatar
                        try
                        {
@@ -369,13 +411,19 @@ namespace GitgCommit
 
                                model.begin_header(_("Staged"));
 
+                               SidebarFile? current_staged = null;
+                               SidebarFile? current_unstaged = null;
+
                                if (staged.length == 0)
                                {
                                        model.append_dummy(_("No staged files"));
                                }
                                else
                                {
-                                       append_files(model, staged, on_staged_activated);
+                                       current_staged = append_files(model,
+                                                                     staged,
+                                                                     currentfile,
+                                                                     on_staged_activated);
                                }
 
                                model.end_header();
@@ -388,7 +436,10 @@ namespace GitgCommit
                                }
                                else
                                {
-                                       append_files(model, unstaged, on_unstaged_activated);
+                                       current_unstaged = append_files(model,
+                                                                       unstaged,
+                                                                       currentfile,
+                                                                       on_unstaged_activated);
                                }
 
                                model.end_header();
@@ -401,7 +452,7 @@ namespace GitgCommit
                                }
                                else
                                {
-                                       append_files(model, untracked, on_unstaged_activated);
+                                       append_files(model, untracked, null, on_unstaged_activated);
                                }
 
                                model.end_header();
@@ -410,6 +461,25 @@ namespace GitgCommit
                                d_has_staged = staged.length != 0;
 
                                d_reloading = false;
+
+                               if (currentfile != null)
+                               {
+                                       SidebarFile? sel = null;
+
+                                       if (d_current_staged)
+                                       {
+                                               sel = (current_staged != null) ? current_staged : 
current_unstaged;
+                                       }
+                                       else
+                                       {
+                                               sel = (current_unstaged != null) ? current_unstaged : 
current_staged;
+                                       }
+
+                                       if (sel != null)
+                                       {
+                                               d_main.sidebar.select(sel);
+                                       }
+                               }
                        });
                }
 
diff --git a/libgitg/gitg-sidebar.vala b/libgitg/gitg-sidebar.vala
index 6948bcb..51a63d7 100644
--- a/libgitg/gitg-sidebar.vala
+++ b/libgitg/gitg-sidebar.vala
@@ -24,62 +24,59 @@ public enum SidebarHint
 {
        NONE,
        HEADER,
-       DEFAULT,
        SEPARATOR,
        DUMMY
 }
 
 public enum SidebarColumn
 {
-       ICON_NAME,
-       NAME,
-       TEXT,
-       HEADER,
        HINT,
        SECTION,
-       OID
+       ITEM
 }
 
-public delegate void SidebarActivated(int numclick);
+public interface SidebarItem : Object
+{
+       public abstract string text { owned get; }
+       public abstract string? icon_name { owned get; }
+
+       public signal void activated(int numclick);
+
+       public virtual void activate(int numclick)
+       {
+               activated(numclick);
+       }
+}
 
 public class SidebarStore : Gtk.TreeStore
 {
-       private class Activated : Object
+       private uint d_sections;
+       private SList<Gtk.TreeIter?> d_parents;
+       private bool d_clearing;
+
+       private class SidebarText : Object, SidebarItem
        {
-               private SidebarActivated d_activated;
+               private string d_text;
 
-               public Activated(owned SidebarActivated? activated)
+               public SidebarText(string text)
                {
-                       d_activated = (owned)activated;
+                       d_text = text;
                }
 
-               public void activate(int numclick)
+               public string text
                {
-                       if (d_activated != null)
-                       {
-                               d_activated(numclick);
-                       }
+                       owned get { return d_text; }
                }
-       }
 
-       private Activated[] d_callbacks;
-       private uint d_oid;
-       private uint d_sections;
-       private SList<Gtk.TreeIter?> d_parents;
-       private bool d_clearing;
-
-       construct
-       {
-               d_callbacks = new Activated[100];
-               d_callbacks.length = 0;
+               public string? icon_name
+               {
+                       owned get { return null; }
+               }
        }
 
-       private new void append(string                  text,
-                               string?                 name,
-                               string?                 icon_name,
-                               uint                    hint,
-                               owned SidebarActivated? callback,
-                               out Gtk.TreeIter        iter)
+       private void append_real(SidebarItem      item,
+                                uint             hint,
+                                out Gtk.TreeIter iter)
        {
                if (d_parents != null)
                {
@@ -91,56 +88,32 @@ public class SidebarStore : Gtk.TreeStore
                }
 
                @set(iter,
-                    SidebarColumn.ICON_NAME, icon_name,
-                    SidebarColumn.NAME, name,
-                    hint == SidebarHint.HEADER ? SidebarColumn.HEADER : SidebarColumn.TEXT, text,
+                    SidebarColumn.ITEM, item,
                     SidebarColumn.HINT, hint,
-                    SidebarColumn.SECTION, d_sections,
-                    SidebarColumn.OID, d_oid);
-
-               d_callbacks += new Activated((owned)callback);
-               ++d_oid;
-       }
-
-       public SidebarStore append_dummy(string                  text,
-                                        string?                 name = null,
-                                        string?                 icon_name = null,
-                                        owned SidebarActivated? callback = null)
-       {
-               Gtk.TreeIter iter;
-               append(text, name, icon_name, SidebarHint.DUMMY, (owned)callback, out iter);
-
-               return this;
+                    SidebarColumn.SECTION, d_sections);
        }
 
-       public SidebarStore append_normal(string                  text,
-                                         string?                 name = null,
-                                         string?                 icon_name = null,
-                                         owned SidebarActivated? callback = null)
+       public SidebarStore append_dummy(string text)
        {
                Gtk.TreeIter iter;
-               append(text, name, icon_name, SidebarHint.NONE, (owned)callback, out iter);
+               append_real(new SidebarText(text), SidebarHint.DUMMY, out iter);
 
                return this;
        }
 
-       public SidebarStore append_default(string                  text,
-                                          string?                 name = null,
-                                          string?                 icon_name = null,
-                                          owned SidebarActivated? callback = null)
+       public new SidebarStore append(SidebarItem item)
        {
                Gtk.TreeIter iter;
-               append(text, name, icon_name, SidebarHint.DEFAULT, (owned)callback, out iter);
+               append_real(item, SidebarHint.NONE, out iter);
 
                return this;
        }
 
-       public SidebarStore begin_header(string  text,
-                                        string? icon_name = null)
+       public SidebarStore begin_header(string text)
        {
                Gtk.TreeIter iter;
 
-               append(text, null, icon_name, SidebarHint.HEADER, null, out iter);
+               append_real(new SidebarText(text), SidebarHint.HEADER, out iter);
                d_parents.prepend(iter);
 
                return this;
@@ -178,20 +151,27 @@ public class SidebarStore : Gtk.TreeStore
                base.clear();
                d_clearing = false;
 
-               d_oid = 0;
                d_sections = 0;
-               d_callbacks.length = 0;
+       }
+
+       public SidebarItem item_for_iter(Gtk.TreeIter iter)
+       {
+               SidebarItem item;
+
+               @get(iter, SidebarColumn.ITEM, out item);
+
+               return item;
        }
 
        public void activate(Gtk.TreeIter iter, int numclick)
        {
-               uint oid;
+               SidebarItem? item;
 
-               @get(iter, SidebarColumn.OID, out oid);
+               @get(iter, SidebarColumn.ITEM, out item);
 
-               if (d_callbacks[oid] != null)
+               if (item != null)
                {
-                       d_callbacks[oid].activate(numclick);
+                       item.activate(numclick);
                }
        }
 }
@@ -216,26 +196,37 @@ public class Sidebar : Gtk.TreeView
        construct
        {
                d_column.set_cell_data_func(d_renderer_icon, (layout, cell, model, iter) => {
-                       string? icon_name;
-                       model.get(iter, SidebarColumn.ICON_NAME, out icon_name);
+                       SidebarItem item;
+                       model.get(iter, SidebarColumn.ITEM, out item);
+
+                       cell.visible = (item.icon_name != null);
 
-                       cell.visible = (icon_name != null);
+                       var r = (Gtk.CellRendererPixbuf)cell;
+                       r.icon_name = item.icon_name;
                });
 
                d_column.set_cell_data_func(d_renderer_header, (layout, cell, model, iter) => {
                        SidebarHint hint;
-                       model.get(iter, SidebarColumn.HINT, out hint);
+                       SidebarItem item;
+
+                       model.get(iter, SidebarColumn.HINT, out hint, SidebarColumn.ITEM, out item);
 
                        cell.visible = (hint == SidebarHint.HEADER);
+
+                       var r = (Gtk.CellRendererText)cell;
+                       r.text = item.text;
                });
 
                d_column.set_cell_data_func(d_renderer_text, (layout, cell, model, iter) => {
                        SidebarHint hint;
-                       model.get(iter, SidebarColumn.HINT, out hint);
+                       SidebarItem item;
+
+                       model.get(iter, SidebarColumn.HINT, out hint, SidebarColumn.ITEM, out item);
 
                        cell.visible = (hint != SidebarHint.HEADER);
 
                        var r = (Gtk.CellRendererText)cell;
+                       r.text = item.text;
 
                        if (hint == SidebarHint.DUMMY)
                        {
@@ -287,6 +278,32 @@ public class Sidebar : Gtk.TreeView
                });
        }
 
+       public T? get_selected_item<T>()
+       {
+               var sel = get_selection();
+               Gtk.TreeIter iter;
+
+               if (sel.get_selected(null, out iter))
+               {
+                       return (T)model.item_for_iter(iter);
+               }
+
+               return null;
+       }
+
+       public void select(SidebarItem item)
+       {
+               model.foreach((m, path, iter) => {
+                       if (model.item_for_iter(iter) == item)
+                       {
+                               get_selection().select_iter(iter);
+                               return true;
+                       }
+
+                       return false;
+               });
+       }
+
        protected override void row_activated(Gtk.TreePath path, Gtk.TreeViewColumn column)
        {
                if (model.clearing)
diff --git a/libgitg/resources/sidebar-view.ui b/libgitg/resources/sidebar-view.ui
index 4a32e8c..1f53fd0 100644
--- a/libgitg/resources/sidebar-view.ui
+++ b/libgitg/resources/sidebar-view.ui
@@ -24,9 +24,6 @@
           <object class="GtkCellRendererPixbuf" id="renderer_icon">
             <property name="follow_state">True</property>
           </object>
-          <attributes>
-            <attribute name="icon_name">0</attribute>
-          </attributes>
           <cell-packing>
             <property name="expand">False</property>
           </cell-packing>
@@ -37,9 +34,6 @@
             <property name="weight">700</property>
             <property name="ellipsize">middle</property>
           </object>
-          <attributes>
-            <attribute name="text">3</attribute>
-          </attributes>
           <cell-packing>
             <property name="expand">True</property>
           </cell-packing>
@@ -48,9 +42,6 @@
           <object class="GtkCellRendererText" id="renderer_text">
             <property name="ellipsize">middle</property>
           </object>
-          <attributes>
-            <attribute name="text">2</attribute>
-          </attributes>
           <cell-packing>
             <property name="expand">True</property>
           </cell-packing>
@@ -60,13 +51,9 @@
   </template>
   <object class="GitgSidebarStore" id="sidebar_store">
     <columns>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-      <column type="guint"/>
       <column type="guint"/>
       <column type="guint"/>
+      <column type="GitgSidebarItem"/>
     </columns>
   </object>
 </interface>


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