[meld] meld.ui: Add a prototype encoding selector
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] meld.ui: Add a prototype encoding selector
- Date: Sat, 25 Nov 2017 22:06:42 +0000 (UTC)
commit 78089f8d1cbd8b75fed9b082488ed66466f0a656
Author: Kai Willadsen <kai willadsen gmail com>
Date: Fri Oct 27 06:56:52 2017 +1000
meld.ui: Add a prototype encoding selector
Currently this is UI-only, and doesn't actually change any document
encoding stuff.
data/ui/encoding-selector.ui | 83 +++++++++++++++++++++++++++++++++++++++
meld/ui/bufferselectors.py | 38 ++++++++++++++++++
meld/ui/listselector.py | 88 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 209 insertions(+), 0 deletions(-)
---
diff --git a/data/ui/encoding-selector.ui b/data/ui/encoding-selector.ui
new file mode 100644
index 0000000..151744a
--- /dev/null
+++ b/data/ui/encoding-selector.ui
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.8 -->
+ <object class="GtkListStore" id="liststore">
+ <columns>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ <!-- column-name encoding -->
+ <column type="GtkSourceEncoding"/>
+ </columns>
+ </object>
+ <object class="GtkTreeModelFilter" id="treemodelfilter">
+ <property name="child_model">liststore</property>
+ </object>
+ <template class="EncodingSelector" parent="GtkGrid">
+ <property name="width_request">300</property>
+ <property name="height_request">400</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="has_focus">False</property>
+ <property name="is_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="border_width">6</property>
+ <child>
+ <object class="GtkSearchEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="is_focus">False</property>
+ <property name="activates_default">True</property>
+ <property name="placeholder_text" translatable="yes">Search text encoding...</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">False</property>
+ <property name="is_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">False</property>
+ <property name="is_focus">False</property>
+ <property name="model">treemodelfilter</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="enable_search">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview_selection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/meld/ui/bufferselectors.py b/meld/ui/bufferselectors.py
new file mode 100644
index 0000000..d01cece
--- /dev/null
+++ b/meld/ui/bufferselectors.py
@@ -0,0 +1,38 @@
+
+from gi.repository import GLib
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import GtkSource
+
+from meld.conf import _, ui_file
+from meld.ui.listselector import FilteredListSelector
+
+
+class EncodingSelector(FilteredListSelector, Gtk.Grid):
+ # The subclassing here is weird; the Selector must directly
+ # subclass Gtk.Grid, or the template building explodes.
+
+ __gtype_name__ = 'EncodingSelector'
+
+ __gsignals__ = {
+ 'encoding-selected': (
+ GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
+ None, (GtkSource.Encoding,)),
+ }
+
+ # These exist solely to make subclassing easier.
+ value_accessor = 'get_charset'
+ change_signal_name = 'encoding-selected'
+
+ def populate_model(self):
+ for enc in GtkSource.Encoding.get_all():
+ self.liststore.append((self.get_value_label(enc), enc))
+
+ def get_value_label(self, enc):
+ return _('{name} ({charset})').format(
+ name=enc.get_name(), charset=enc.get_charset())
+
+
+template = open(ui_file('encoding-selector.ui'), 'rb').read()
+template_bytes = GLib.Bytes.new(template)
+EncodingSelector.set_template(template_bytes)
diff --git a/meld/ui/listselector.py b/meld/ui/listselector.py
new file mode 100644
index 0000000..99d2d72
--- /dev/null
+++ b/meld/ui/listselector.py
@@ -0,0 +1,88 @@
+
+from gi.repository import Gtk
+
+
+class TemplateHackMixin(object):
+
+ def get_template_child(self, widget_type, name):
+ # Taken from an in-progress patch on bgo#701843
+
+ def get_template_child(widget, widget_type, name):
+ # Explicitly use gtk_buildable_get_name() because it is masked by
+ # gtk_widget_get_name() in GI.
+ if isinstance(widget, widget_type) and \
+ isinstance(widget, Gtk.Buildable) and \
+ Gtk.Buildable.get_name(widget) == name:
+ return widget
+
+ if isinstance(widget, Gtk.Container):
+ for child in widget.get_children():
+ result = get_template_child(child, widget_type, name)
+ if result is not None:
+ return result
+
+ return get_template_child(self, widget_type, name)
+
+
+class FilteredListSelector(TemplateHackMixin):
+
+ __gtype_name__ = 'FilteredListSelector'
+
+ NAME_COLUMN, VALUE_COLUMN = 0, 1
+
+ def __init__(self):
+ Gtk.Grid.__init__(self)
+ self.init_template()
+
+ self.entry = self.get_template_child(Gtk.SearchEntry, 'entry')
+ self.treeview = self.get_template_child(Gtk.TreeView, 'treeview')
+ self.treeview_selection = self.treeview.get_selection()
+ # FIXME: Should be able to access as a template child, but can't.
+ self.listfilter = self.treeview.get_model()
+ self.liststore = self.listfilter.get_model()
+
+ self.populate_model()
+ self.filter_string = ''
+ self.entry.connect('changed', self.on_entry_changed)
+ self.listfilter.set_visible_func(self.name_filter)
+
+ self.entry.connect('activate', self.on_activate)
+ self.treeview.connect('row-activated', self.on_activate)
+
+ def populate_model(self):
+ raise NotImplementedError
+
+ def select_value(self, value):
+ if not value:
+ return
+
+ new_value_getter = getattr(value, self.value_accessor)
+ for row in self.liststore:
+ row_value = row[self.VALUE_COLUMN]
+ if not row_value:
+ continue
+ old_value_getter = getattr(row_value, self.value_accessor)
+ if old_value_getter() != new_value_getter():
+ continue
+ self.treeview_selection.select_path(row.path)
+ self.treeview.scroll_to_cell(row.path, None, True, 0.5, 0)
+
+ def name_filter(self, model, it, *args):
+ if not self.filter_string:
+ return True
+ name = model.get_value(it, self.NAME_COLUMN).lower()
+ return self.filter_string.lower() in name
+
+ def on_entry_changed(self, entry):
+ self.filter_string = entry.get_text()
+ self.listfilter.refilter()
+ first = self.listfilter.get_iter_first()
+ if first:
+ self.treeview_selection.select_iter(first)
+
+ def on_activate(self, *args):
+ model, it = self.treeview_selection.get_selected()
+ if not it:
+ return
+ value = model.get_value(it, self.VALUE_COLUMN)
+ self.emit(self.change_signal_name, value)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]