[meld] Implemented reorderable and hideable columns



commit e3969418e5b46192601e6a454495a84c0952c9fb
Author: Philipp MÃller <descpl yahoo de>
Date:   Sat Jan 5 07:21:19 2013 +1000

    Implemented reorderable and hideable columns

 data/ui/preferences.ui |  136 ++++++++++++++++++++++++++++++++++++++++++++++++
 meld/dirdiff.py        |   97 ++++++++++++++++++++++------------
 meld/preferences.py    |   47 +++++++++++++++++
 3 files changed, 247 insertions(+), 33 deletions(-)
---
diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui
index a686f6e..55d1b85 100644
--- a/data/ui/preferences.ui
+++ b/data/ui/preferences.ui
@@ -9,6 +9,28 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkListStore" id="liststore1">
+    <columns>
+      <!-- column-name active -->
+      <column type="gboolean"/>
+      <!-- column-name column_name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0">False</col>
+        <col id="1" translatable="yes">Name</col>
+      </row>
+      <row>
+        <col id="0">False</col>
+        <col id="1" translatable="yes">Modification date</col>
+      </row>
+      <row>
+        <col id="0">False</col>
+        <col id="1" translatable="yes">Size</col>
+      </row>
+    </data>
+  </object>
   <object class="GtkDialog" id="preferencesdialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -809,6 +831,120 @@
                 <property name="label" translatable="yes">Encoding</property>
               </object>
               <packing>
+                <property name="position">3</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="columns_ta">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">12</property>
+                <property name="bottom_padding">12</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">12</property>
+                <child>
+                  <object class="GtkVBox" id="columns_tab">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">automatic</property>
+                        <property name="vscrollbar_policy">automatic</property>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="columns_treeview">
+                            <property name="height_request">150</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="headers_clickable">False</property>
+                            <property name="search_column">0</property>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="active_column">
+                                <property name="title" translatable="yes">Active</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cr_active"/>
+                                  <attributes>
+                                    <attribute name="active">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="name_column">
+                                <property name="title" translatable="yes">Column name</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="cr_name"/>
+                                  <attributes>
+                                    <attribute name="text">1</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkToolbar" id="columns_toolbar">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkToolButton" id="column_up">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="use_action_appearance">False</property>
+                            <property name="label" translatable="yes">Move up</property>
+                            <property name="use_underline">True</property>
+                            <property name="stock_id">gtk-go-up</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkToolButton" id="column_down">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="use_action_appearance">False</property>
+                            <property name="label" translatable="yes">Move down</property>
+                            <property name="use_underline">True</property>
+                            <property name="stock_id">gtk-go-down</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="homogeneous">True</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="Columns">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Columns</property>
+              </object>
+              <packing>
                 <property name="position">4</property>
                 <property name="tab_fill">False</property>
               </packing>
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 0da2f31..841a4ca 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -295,39 +295,9 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
         permissions_label.show()
         self.status_info_labels = [lastchanged_label, permissions_label]
 
+        self.columns_dict = [{}, {}, {}]  # one column-dict for each treeview
+        self.create_treeview_columns(self.prefs.dirdiff_columns)
         for i in range(3):
-            # Create icon and filename CellRenderer
-            column = gtk.TreeViewColumn()
-            rentext = gtk.CellRendererText()
-            renicon = emblemcellrenderer.EmblemCellRenderer()
-            column.pack_start(renicon, expand=0)
-            column.pack_start(rentext, expand=1)
-            col_index = self.model.column_index
-            column.set_attributes(rentext, text=col_index(tree.COL_TEXT,i),
-                                  foreground_gdk=col_index(tree.COL_FG, i),
-                                  style=col_index(tree.COL_STYLE, i),
-                                  weight=col_index(tree.COL_WEIGHT, i),
-                                  strikethrough=col_index(tree.COL_STRIKE, i))
-            column.set_attributes(renicon,
-                                  icon_name=col_index(tree.COL_ICON, i),
-                                  emblem_name=col_index(COL_EMBLEM, i),
-                                  icon_tint=col_index(tree.COL_TINT, i))
-            self.treeview[i].append_column(column)
-
-            # Create file size CellRenderer
-            column = gtk.TreeViewColumn()
-            rentext = gtk.CellRendererText()
-            column.pack_start(rentext, expand=1)
-            column.set_attributes(rentext, markup=col_index(COL_SIZE, i))
-            self.treeview[i].append_column(column)
-
-            # Create date-time CellRenderer
-            column = gtk.TreeViewColumn()
-            rentext = gtk.CellRendererText()
-            column.pack_start(rentext, expand=1)
-            column.set_attributes(rentext, markup=col_index(COL_TIME, i))
-            self.treeview[i].append_column(column)
-
             self.treeview[i].get_selection().set_mode(gtk.SELECTION_MULTIPLE)
             self.scrolledwindow[i].get_vadjustment().connect("value-changed", self._sync_vscroll )
             self.scrolledwindow[i].get_hadjustment().connect("value-changed", self._sync_hscroll )
@@ -1109,7 +1079,9 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
                 self.model.set_value(it, TIME, time_str)
 
                 def natural_size(bytes):
-                    suffixes = ('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
+                    suffixes = (
+                            'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
+                            )
                     size = float(bytes)
                     unit = 0
                     while size > 1000 and unit < len(suffixes) - 1:
@@ -1298,3 +1270,62 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
             app.disconnect(h)
 
         return gtk.RESPONSE_OK
+
+    def update_treeview_columns(self, columns, showheaders=None):
+        """Adjusts visibility and order or columns, second arg
+        as in create_treeview_columns"""
+        for i in range(3):
+            num_visible_cols = 1
+            last_column = self.treeview[i].get_column(0)
+            for line in columns:
+                column_name, column_visibility = line.rsplit(" ", 1)
+                column_visibility = bool(int(column_visibility))
+                num_visible_cols = num_visible_cols + int(column_visibility)
+                current_column = self.columns_dict[i][column_name]
+                current_column.set_visible(column_visibility)
+                self.treeview[i].move_column_after(current_column, last_column)
+                last_column = current_column
+            self.treeview[i].set_headers_visible(num_visible_cols != 1)
+
+    def create_treeview_columns(self, columns, showheaders=None):
+        """Creates the columns properly, second argument is a string
+        describing visiblity and order of columns."""
+        for i in range(3):
+            last_column = None
+            col_index = self.model.column_index
+            # Create icon and filename CellRenderer
+            column = gtk.TreeViewColumn(_("Name"))
+            rentext = gtk.CellRendererText()
+            renicon = emblemcellrenderer.EmblemCellRenderer()
+            column.pack_start(renicon, expand=0)
+            column.pack_start(rentext, expand=1)
+            column.set_attributes(rentext, text=col_index(tree.COL_TEXT, i),
+                                  foreground_gdk=col_index(tree.COL_FG, i),
+                                  style=col_index(tree.COL_STYLE, i),
+                                  weight=col_index(tree.COL_WEIGHT, i),
+                                  strikethrough=col_index(tree.COL_STRIKE, i))
+            column.set_attributes(renicon,
+                                  icon_name=col_index(tree.COL_ICON, i),
+                                  emblem_name=col_index(COL_EMBLEM, i),
+                                  icon_tint=col_index(tree.COL_TINT, i))
+            self.treeview[i].append_column(column)
+            self.columns_dict[i]["name"] = column
+            # Create file size CellRenderer
+            column = gtk.TreeViewColumn(_("Size"))
+            rentext = gtk.CellRendererText()
+            column.pack_start(rentext, expand=1)
+            column.set_attributes(rentext, markup=col_index(COL_SIZE, i))
+            self.treeview[i].append_column(column)
+            self.columns_dict[i]["size"] = column
+            # Create date-time CellRenderer
+            column = gtk.TreeViewColumn(_("Modification time"))
+            rentext = gtk.CellRendererText()
+            column.pack_start(rentext, expand=1)
+            column.set_attributes(rentext, markup=col_index(COL_TIME, i))
+            self.treeview[i].append_column(column)
+            self.columns_dict[i]["modification time"] = column
+        self.update_treeview_columns(columns, showheaders)
+
+    def on_preference_changed(self, key, value):
+        if key == "dirdiff_columns":
+            self.update_treeview_columns(value)
diff --git a/meld/preferences.py b/meld/preferences.py
index 4c61022..d9a0ede 100644
--- a/meld/preferences.py
+++ b/meld/preferences.py
@@ -146,8 +146,50 @@ class PreferencesDialog(gnomeglade.Component):
         self.checkbutton_ignore_blank_lines.set_active( self.prefs.ignore_blank_lines )
         # encoding
         self.entry_text_codecs.set_text( self.prefs.text_codecs )
+
+        # columns
+        column_model = gtk.ListStore(bool, str)
+        self.columns_treeview.set_model(column_model)
+        for column in self.prefs.dirdiff_columns:
+            column_name, visibility = column.rsplit(" ", 1)
+            visibility = bool(int(visibility))
+            column_model.append([visibility, _(column_name.capitalize())])
+        self.cr_active.set_property("activatable", True)
+        self.active_column.add_attribute(self.cr_active, "active", 0)
+        self.name_column.add_attribute(self.cr_name, "text", 1)
+        self.cr_active.connect("toggled",
+                self.on_cr_active_toggled, column_model)
+        self.column_up.connect("clicked", self.on_column_up_clicked)
+        self.column_down.connect("clicked", self.on_column_down_clicked)
         self.widget.show()
 
+    def _get_column_selected(self):
+        (model, it) = self.columns_treeview.get_selection().get_selected()
+        if it:
+            path = model.get_path(it)[0]
+        else:
+            path = None
+        return (model, it, path)
+
+    def on_column_up_clicked(self, button):
+        (model, it, path) = self._get_column_selected()
+        model.swap(it, model.get_iter(path - 1))
+        self.update_columns(model)
+
+    def on_column_down_clicked(self, button):
+        (model, it, path) = self._get_column_selected()
+        model.swap(it, model.get_iter(path + 1))
+        self.update_columns(model)
+
+    def on_cr_active_toggled(self, cell, path, model):
+        model[path][0] = not model[path][0]
+        self.update_columns(model)
+
+    def update_columns(self, model):
+        self.prefs.dirdiff_columns = [
+                "%s %d" % (column[1].lower(), int(column[0])) for column in model
+                ]
+
     def on_fontpicker_font_set(self, picker):
         self.prefs.custom_font = picker.get_font_name()
 
@@ -254,6 +296,11 @@ class MeldPreferences(prefs.Preferences):
                                           ['normal', 'modified', 'new']),
         "vc_status_filters": prefs.Value(prefs.LIST,
                                          ['flatten', 'modified']),
+        # Currently, we're using a quite simple format to store the columns:
+        # each line contains a column name followed by a 1 or a 0
+        # depending on whether the column is visible or not.
+        "dirdiff_columns": prefs.Value(prefs.LIST,
+                                         ["size 1", "modification time 1"]),
     }
 
     def __init__(self):



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