[meld/ui-next] filediff: Add a per-view text filter menu button



commit 9d2514efc65fe6cea161bcacc6328936fb313b67
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Mar 23 10:47:06 2019 +1000

    filediff: Add a per-view text filter menu button
    
    This mimics (and in fact is mostly copy-paste of) the DirDiff filter
    menu handling.

 meld/const.py                  |  1 +
 meld/filediff.py               | 28 ++++++++++++++++++++++++++--
 meld/meldwindow.py             | 22 +++++++++++++++++++++-
 meld/resources/gtk/menus.ui    |  5 +++++
 meld/resources/ui/appwindow.ui | 15 +++++++++++++++
 5 files changed, 68 insertions(+), 3 deletions(-)
---
diff --git a/meld/const.py b/meld/const.py
index 762024a7..f4195775 100644
--- a/meld/const.py
+++ b/meld/const.py
@@ -28,3 +28,4 @@ NEWLINES = {
 }
 
 FILE_FILTER_ACTION_FORMAT = 'folder-custom-filter-{}'
+TEXT_FILTER_ACTION_FORMAT = 'text-custom-filter-{}'
diff --git a/meld/filediff.py b/meld/filediff.py
index b277624c..0ee4a729 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -29,7 +29,12 @@ from gi.repository import GtkSource
 # TODO: Don't from-import whole modules
 from meld import misc
 from meld.conf import _
-from meld.const import ActionMode, ChunkAction, NEWLINES
+from meld.const import (
+    ActionMode,
+    ChunkAction,
+    NEWLINES,
+    TEXT_FILTER_ACTION_FORMAT,
+)
 from meld.gutterrendererchunk import GutterRendererChunkLines
 from meld.iohelpers import prompt_save_filename
 from meld.matchers.diffutil import Differ, merged_chunk_order
@@ -239,7 +244,6 @@ class FileDiff(Gtk.VBox, MeldDoc):
         self.buffer_texts = [BufferLines(b) for b in self.textbuffer]
         self.undosequence = UndoSequence(self.textbuffer)
         self.text_filters = []
-        self.create_text_filters()
         self.settings_handlers = [
             meldsettings.connect(
                 "text-filters-changed", self.on_text_filters_changed)
@@ -340,6 +344,8 @@ class FileDiff(Gtk.VBox, MeldDoc):
         self.toolbar_actions = builder.get_object('view-toolbar')
         self.copy_action_button = builder.get_object('copy_action_button')
 
+        self.create_text_filters()
+
         # Handle sourcemap visibility binding
         self.bind_property(
             'show-sourcemap', self.sourcemap_revealer, 'reveal-child',
@@ -473,6 +479,11 @@ class FileDiff(Gtk.VBox, MeldDoc):
         if relevant_change:
             self.refresh_comparison()
 
+    def _update_text_filter(self, action, state):
+        self._action_text_filter_map[action].active = state.get_boolean()
+        action.set_state(state)
+        self.refresh_comparison()
+
     def create_text_filters(self):
         # In contrast to file filters, ordering of text filters can matter
         old_active = [f.filter_string for f in self.text_filters if f.active]
@@ -481,7 +492,20 @@ class FileDiff(Gtk.VBox, MeldDoc):
         ]
         active_filters_changed = old_active != new_active
 
+        # TODO: Rework text_filters to use a map-like structure so that we
+        # don't need _action_text_filter_map.
+        self._action_text_filter_map = {}
         self.text_filters = [copy.copy(f) for f in meldsettings.text_filters]
+        for i, filt in enumerate(self.text_filters):
+            action = Gio.SimpleAction.new_stateful(
+                name=TEXT_FILTER_ACTION_FORMAT.format(i),
+                parameter_type=None,
+                state=GLib.Variant.new_boolean(filt.active),
+            )
+            action.connect('change-state', self._update_text_filter)
+            action.set_enabled(filt.filter is not None)
+            self.view_action_group.add_action(action)
+            self._action_text_filter_map[action] = filt
 
         return active_filters_changed
 
diff --git a/meld/meldwindow.py b/meld/meldwindow.py
index 5ebb3394..02ee81fc 100644
--- a/meld/meldwindow.py
+++ b/meld/meldwindow.py
@@ -26,7 +26,7 @@ from gi.repository import Gtk
 import meld.ui.gladesupport  # noqa: F401
 import meld.ui.util
 from meld.conf import _
-from meld.const import FILE_FILTER_ACTION_FORMAT
+from meld.const import FILE_FILTER_ACTION_FORMAT, TEXT_FILTER_ACTION_FORMAT
 from meld.dirdiff import DirDiff
 from meld.filediff import FileDiff
 from meld.filemerge import FileMerge
@@ -51,6 +51,7 @@ class MeldWindow(Gtk.ApplicationWindow):
 
     appvbox = Template.Child("appvbox")
     folder_filter_button = Template.Child()
+    text_filter_button = Template.Child()
     gear_menu_button = Template.Child("gear_menu_button")
     notebook = Template.Child("notebook")
     spinner = Template.Child("spinner")
@@ -116,6 +117,10 @@ class MeldWindow(Gtk.ApplicationWindow):
         self.gear_menu_button.set_popover(
             Gtk.Popover.new_from_model(self.gear_menu_button, menu))
 
+        filter_model = app.get_menu_by_id("text-filter-menu")
+        self.text_filter_button.set_popover(
+            Gtk.Popover.new_from_model(self.text_filter_button, filter_model))
+
         filter_menu = app.get_menu_by_id("folder-status-filter-menu")
         self.folder_filter_button.set_popover(
             Gtk.Popover.new_from_model(self.folder_filter_button, filter_menu))
@@ -124,8 +129,11 @@ class MeldWindow(Gtk.ApplicationWindow):
         self.vc_filter_button.set_popover(
             Gtk.Popover.new_from_model(self.vc_filter_button, vc_filter_model))
 
+        self.update_text_filters()
         self.update_filename_filters()
         self.settings_handlers = [
+            meldsettings.connect(
+                "text-filters-changed", self.update_text_filters),
             meldsettings.connect(
                 "file-filters-changed", self.update_filename_filters),
         ]
@@ -144,6 +152,18 @@ class MeldWindow(Gtk.ApplicationWindow):
         filter_model = app.get_menu_by_id("folder-status-filter-menu")
         replace_menu_section(filter_model, section)
 
+    def update_text_filters(self, *args):
+        filter_items_model = Gio.Menu()
+        for i, filt in enumerate(meldsettings.text_filters):
+            name = TEXT_FILTER_ACTION_FORMAT.format(i)
+            filter_items_model.append(
+                label=filt.label, detailed_action=f'view.{name}')
+        section = Gio.MenuItem.new_section(None, filter_items_model)
+        section.set_attribute([("id", "s", "custom-filter-section")])
+        app = self.get_application()
+        filter_model = app.get_menu_by_id("text-filter-menu")
+        replace_menu_section(filter_model, section)
+
     def on_widget_drag_data_received(
             self, wid, context, x, y, selection_data, info, time):
         uris = selection_data.get_uris()
diff --git a/meld/resources/gtk/menus.ui b/meld/resources/gtk/menus.ui
index 11f51659..3020f783 100644
--- a/meld/resources/gtk/menus.ui
+++ b/meld/resources/gtk/menus.ui
@@ -127,6 +127,11 @@
       </item>
     </section>
   </menu>
+  <menu id="text-filter-menu">
+    <section>
+      <attribute name="id">custom-filter-section</attribute>
+    </section>
+  </menu>
   <menu id="folder-status-filter-menu">
     <section>
       <attribute name="id">status-section</attribute>
diff --git a/meld/resources/ui/appwindow.ui b/meld/resources/ui/appwindow.ui
index bbf1d114..02fc553d 100644
--- a/meld/resources/ui/appwindow.ui
+++ b/meld/resources/ui/appwindow.ui
@@ -221,6 +221,21 @@
             <property name="pack-type">end</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkMenuButton" id="text_filter_button">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Text Filters</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack-type">end</property>
+          </packing>
+        </child>
       </object>
     </child>
 


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