[meld] Generalise ListWidget and use it to implement the column selector



commit cbe7fe652a6cc5b10858d8c69861319ce827782e
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Jan 6 05:23:19 2013 +1000

    Generalise ListWidget and use it to implement the column selector
    
    The ListWidget class + UI was always intended to be generic, but
    somehow that never works out. For code reuse and a bit of simplicity,
    this commit moves the new column prefence list to use a slightly
    reworked ListWidget, but with its own UI definition.

 data/ui/EditableList.ui |  167 ++++++++++++++++++++++++++++++++++++++++++++++-
 data/ui/preferences.ui  |  116 ++++++++++-----------------------
 meld/preferences.py     |   76 ++++++++++------------
 meld/ui/listwidget.py   |   14 ++--
 4 files changed, 241 insertions(+), 132 deletions(-)
---
diff --git a/data/ui/EditableList.ui b/data/ui/EditableList.ui
index e37683f..120c857 100644
--- a/data/ui/EditableList.ui
+++ b/data/ui/EditableList.ui
@@ -1,7 +1,172 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy project-wide -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkListStore" id="ColumnsListStore">
+    <columns>
+      <!-- column-name Active -->
+      <column type="gboolean"/>
+      <!-- column-name Name -->
+      <column type="gchararray"/>
+    </columns>
+    <signal name="row-inserted" handler="_update_sensitivity" swapped="no"/>
+    <signal name="rows-reordered" handler="_update_sensitivity" swapped="no"/>
+  </object>
+  <object class="GtkWindow" id="ColumnsListWindow">
+    <property name="can_focus">False</property>
+    <property name="title" translatable="yes">Editable List</property>
+    <child>
+      <object class="GtkAlignment" id="columns_ta">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="top_padding">8</property>
+        <property name="bottom_padding">8</property>
+        <property name="left_padding">8</property>
+        <property name="right_padding">8</property>
+        <child>
+          <object class="GtkVBox" id="columns_tab">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow2">
+                <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="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">ColumnsListStore</property>
+                    <property name="headers_clickable">False</property>
+                    <property name="reorderable">True</property>
+                    <property name="search_column">0</property>
+                    <property name="show_expanders">False</property>
+                    <property name="rubber_banding">True</property>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="active_column">
+                        <property name="title" translatable="yes">Active</property>
+                        <child>
+                          <object class="GtkCellRendererToggle" id="cr_active">
+                            <signal name="toggled" handler="on_cellrenderertoggle_toggled" swapped="no"/>
+                          </object>
+                          <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="list_toolbar">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="toolbar_style">icons</property>
+                <property name="show_arrow">False</property>
+                <property name="icon_size">1</property>
+                <property name="icon_size_set">True</property>
+                <child>
+                  <object class="GtkToolButton" id="add">
+                    <property name="can_focus">False</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="label" translatable="yes">_Add</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">list-add</property>
+                    <signal name="clicked" handler="on_add_clicked" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToolButton" id="remove">
+                    <property name="can_focus">False</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="label" translatable="yes">_Remove</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">list-remove</property>
+                    <signal name="clicked" handler="on_remove_clicked" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSeparatorToolItem" id="up_down_sep">
+                    <property name="visible">False</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToolButton" id="move_up">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="tooltip_text" translatable="yes">Move item up</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="label" translatable="yes">Move _Up</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">go-up</property>
+                    <signal name="clicked" handler="on_move_up_clicked" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="homogeneous">True</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToolButton" id="move_down">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="tooltip_text" translatable="yes">Move item down</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="label" translatable="yes">Move _Down</property>
+                    <property name="use_underline">True</property>
+                    <property name="icon_name">go-down</property>
+                    <signal name="clicked" handler="on_move_down_clicked" swapped="no"/>
+                  </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>
+    </child>
+  </object>
   <object class="GtkListStore" id="EditableListStore">
     <columns>
       <!-- column-name Name -->
diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui
index 55d1b85..b55ecc6 100644
--- a/data/ui/preferences.ui
+++ b/data/ui/preferences.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <!-- interface-requires gtk+ 2.8 -->
+  <requires lib="gtk+" version="2.18"/>
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkAdjustment" id="adjustment1">
     <property name="lower">1</property>
@@ -9,28 +9,6 @@
     <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>
@@ -836,102 +814,76 @@
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="columns_ta">
+              <object class="GtkVBox" id="columns_tab">
                 <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>
+                <property name="border_width">12</property>
+                <property name="spacing">12</property>
                 <child>
-                  <object class="GtkVBox" id="columns_tab">
+                  <object class="GtkVBox" id="vbox1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="scrolledwindow1">
+                      <object class="GtkLabel" id="label3">
                         <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>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Visible columns</property>
+                        <property name="use_markup">True</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkToolbar" id="columns_toolbar">
+                      <object class="GtkHBox" id="hbox1">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkToolButton" id="column_up">
+                          <object class="GtkLabel" id="label4">
                             <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>
+                            <property name="xpad">12</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkToolButton" id="column_down">
+                          <object class="GtkVBox" id="column_list_vbox">
                             <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>
+                            <child>
+                              <placeholder/>
+                            </child>
                           </object>
                           <packing>
-                            <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
+                        <property name="expand">True</property>
                         <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
                 </child>
               </object>
               <packing>
diff --git a/meld/preferences.py b/meld/preferences.py
index d9a0ede..353de01 100644
--- a/meld/preferences.py
+++ b/meld/preferences.py
@@ -36,7 +36,9 @@ class FilterList(listwidget.ListWidget):
 
     def __init__(self, prefs, key, filter_type):
         default_entry = [_("label"), False, _("pattern"), True]
-        listwidget.ListWidget.__init__(self, default_entry)
+        listwidget.ListWidget.__init__(self, "EditableList.ui",
+                                       "list_alignment", ["EditableListStore"],
+                                       "EditableList", default_entry)
         self.prefs = prefs
         self.key = key
         self.filter_type = filter_type
@@ -86,6 +88,34 @@ class FilterList(listwidget.ListWidget):
         setattr(self.prefs, self.key, "\n".join(pref))
 
 
+class ColumnList(listwidget.ListWidget):
+
+    def __init__(self, prefs, key):
+        listwidget.ListWidget.__init__(self, "EditableList.ui",
+                               "columns_ta", ["ColumnsListStore"],
+                               "columns_treeview")
+        self.prefs = prefs
+        self.key = key
+
+        for column in getattr(self.prefs, self.key):
+            column_name, visibility = column.rsplit(" ", 1)
+            visibility = bool(int(visibility))
+            self.model.append([visibility, _(column_name.capitalize())])
+
+        for signal in ('row-changed', 'row-deleted', 'row-inserted',
+                       'rows-reordered'):
+            self.model.connect(signal, self._update_columns)
+
+        self._update_sensitivity()
+
+    def on_cellrenderertoggle_toggled(self, ren, path):
+        self.model[path][0] = not ren.get_active()
+
+    def _update_columns(self, *args):
+        columns = ["%s %d" % (c[1].lower(), int(c[0])) for c in self.model]
+        setattr(self.prefs, self.key, columns)
+
+
 class PreferencesDialog(gnomeglade.Component):
 
     def __init__(self, parent, prefs):
@@ -147,48 +177,10 @@ class PreferencesDialog(gnomeglade.Component):
         # 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()
+        columnlist = ColumnList(self.prefs, "dirdiff_columns")
+        self.column_list_vbox.pack_start(columnlist.widget)
 
-    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
-                ]
+        self.widget.show()
 
     def on_fontpicker_font_set(self, picker):
         self.prefs.custom_font = picker.get_font_name()
diff --git a/meld/ui/listwidget.py b/meld/ui/listwidget.py
index 17c8e52..b20075b 100644
--- a/meld/ui/listwidget.py
+++ b/meld/ui/listwidget.py
@@ -23,12 +23,13 @@ from . import gnomeglade
 
 class ListWidget(gnomeglade.Component):
 
-    def __init__(self, new_row_data=None):
-        gnomeglade.Component.__init__(self, paths.ui_dir("EditableList.ui"),
-                                      "list_alignment", ["EditableListStore"])
+    def __init__(self, ui_file, widget, store, treeview, new_row_data=None):
+        gnomeglade.Component.__init__(self, paths.ui_dir(ui_file),
+                                      widget, store)
         self.new_row_data = new_row_data
-        self.model = self.EditableList.get_model()
-        selection = self.EditableList.get_selection()
+        self.list = getattr(self, treeview)
+        self.model = self.list.get_model()
+        selection = self.list.get_selection()
         selection.connect("changed", self._update_sensitivity)
 
     def _update_sensitivity(self, *args):
@@ -43,7 +44,7 @@ class ListWidget(gnomeglade.Component):
             self.move_down.set_sensitive(path < len(model) - 1)
 
     def _get_selected(self):
-        (model, it) = self.EditableList.get_selection().get_selected()
+        (model, it) = self.list.get_selection().get_selected()
         if it:
             path = model.get_path(it)[0]
         else:
@@ -64,4 +65,3 @@ class ListWidget(gnomeglade.Component):
     def on_move_down_clicked(self, button):
         (model, it, path) = self._get_selected()
         model.swap(it, model.get_iter(path + 1))
-



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