[meld/pathlabel: 3/10] ui.pathlabel: New widget for displaying paths with some helpers




commit 24d9aed7f16f292701d87d6b374389bfc1364c6b
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Mar 24 07:37:02 2019 +1000

    ui.pathlabel: New widget for displaying paths with some helpers

 meld/filediff.py                  |  11 ++--
 meld/resources/meld.gresource.xml |   1 +
 meld/resources/ui/filediff.ui     |  18 ++----
 meld/resources/ui/path-label.ui   | 114 ++++++++++++++++++++++++++++++++++++++
 meld/ui/gladesupport.py           |   1 +
 meld/ui/pathlabel.py              | 101 +++++++++++++++++++++++++++++++++
 po/POTFILES.in                    |   2 +
 7 files changed, 231 insertions(+), 17 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index c9e9d657..ae1dcb29 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -1384,7 +1384,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
         buf.data.savefile = gfile
         buf.data.label = gfile.get_path()
         self.update_buffer_writable(buf)
-        self.filelabel[1].set_text(buf.data.label)
+        self.filelabel[1].props.gfile = gfile
         self.recompute_label()
 
     def _set_save_action_sensitivity(self):
@@ -1480,7 +1480,9 @@ class FileDiff(Gtk.VBox, MeldDoc):
         buf = self.textbuffer[pane]
         buf.data.reset(gfile)
 
-        self.filelabel[pane].set_text(self.textbuffer[pane].data.label)
+        # FIXME: this was self.textbuffer[pane].data.label, which could be
+        # either a custom label or the fallback
+        self.filelabel[pane].props.gfile = gfile
 
         if buf.data.is_special:
             loader = GtkSource.FileLoader.new_from_stream(
@@ -1634,8 +1636,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
         labels = meta.get('labels', ())
         if labels:
             for i, l in enumerate(labels):
-                if l:
-                    self.filelabel[i].set_text(l)
+                self.filelabel[i].props.custom_label = l
 
     def notify_file_changed(self, data):
         try:
@@ -1932,7 +1933,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
             bufdata.label = gfile.get_path()
             bufdata.gfile = gfile
             bufdata.savefile = None
-            self.filelabel[pane].set_text(bufdata.label)
+            self.filelabel[pane].props.gfile = gfile
 
         if not force_overwrite and not bufdata.current_on_disk():
             primary = (
diff --git a/meld/resources/meld.gresource.xml b/meld/resources/meld.gresource.xml
index 3295a462..f57a7068 100644
--- a/meld/resources/meld.gresource.xml
+++ b/meld/resources/meld.gresource.xml
@@ -29,6 +29,7 @@
     <file>ui/new-diff-tab.ui</file>
     <file>ui/notebook-label.ui</file>
     <file>ui/patch-dialog.ui</file>
+    <file>ui/path-label.ui</file>
     <file>ui/preferences.ui</file>
     <file>ui/push-dialog.ui</file>
     <file>ui/recent-selector.ui</file>
diff --git a/meld/resources/ui/filediff.ui b/meld/resources/ui/filediff.ui
index 2cadb783..a5d055bd 100644
--- a/meld/resources/ui/filediff.ui
+++ b/meld/resources/ui/filediff.ui
@@ -67,17 +67,15 @@
                 <property name="can_focus">False</property>
                 <property name="margin_start">12</property>
                 <child>
-                  <object class="GtkLabel" id="filelabel2">
+                  <object class="PathLabel" id="filelabel2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label" translatable="yes">File 3</property>
-                    <property name="xalign">0</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
                   </object>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="homogeneous">False</property>
               </packing>
             </child>
@@ -136,17 +134,15 @@
                 <property name="can_focus">False</property>
                 <property name="margin_start">12</property>
                 <child>
-                  <object class="GtkLabel" id="filelabel1">
+                  <object class="PathLabel" id="filelabel1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label" translatable="yes">File 2</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
-                    <property name="xalign">0</property>
                   </object>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="homogeneous">False</property>
               </packing>
             </child>
@@ -201,17 +197,15 @@
                 <property name="can_focus">False</property>
                 <property name="margin_start">12</property>
                 <child>
-                  <object class="GtkLabel" id="filelabel0">
+                  <object class="PathLabel" id="filelabel0">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label" translatable="yes">File 1</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
-                    <property name="xalign">0</property>
                   </object>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="homogeneous">False</property>
               </packing>
             </child>
diff --git a/meld/resources/ui/path-label.ui b/meld/resources/ui/path-label.ui
new file mode 100644
index 00000000..d5dafc55
--- /dev/null
+++ b/meld/resources/ui/path-label.ui
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkPopover" id="path_popover">
+    <property name="can_focus">True</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">6</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="label" translatable="yes">Path:</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="full_path_label">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="editable">False</property>
+            <property name="width_chars">60</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="homogeneous">True</property>
+            <child>
+              <object class="GtkButton">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="focus_on_click">False</property>
+                <property name="receives_default">False</property>
+                <property name="tooltip_text">Copy Full Path</property>
+                <property name="action_name">widget.copy-full-path</property>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">edit-copy-symbolic</property>
+                  </object>
+                </child>
+                <style>
+                  <class name="image-button"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="focus_on_click">False</property>
+                <property name="receives_default">False</property>
+                <property name="tooltip_text">Open Containing Folder</property>
+                <property name="action_name">widget.open-folder</property>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">folder-open-symbolic</property>
+                  </object>
+                </child>
+                <style>
+                  <class name="image-button"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <style>
+              <class name="linked"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <template class="PathLabel" parent="GtkMenuButton">
+    <property name="can_focus">False</property>
+    <property name="receives_default">False</property>
+    <property name="popover">path_popover</property>
+    <child>
+      <placeholder/>
+    </child>
+  </template>
+</interface>
diff --git a/meld/ui/gladesupport.py b/meld/ui/gladesupport.py
index 40a64629..30a1680e 100644
--- a/meld/ui/gladesupport.py
+++ b/meld/ui/gladesupport.py
@@ -13,5 +13,6 @@ from meld.ui import emblemcellrenderer  # noqa: F401
 from meld.ui import historyentry  # noqa: F401
 from meld.ui import msgarea  # noqa: F401
 from meld.ui import notebook  # noqa: F401
+from meld.ui import pathlabel  # noqa: F401
 from meld.ui import recentselector  # noqa: F401
 from meld.ui import statusbar  # noqa: F401
diff --git a/meld/ui/pathlabel.py b/meld/ui/pathlabel.py
new file mode 100644
index 00000000..a8cf83bc
--- /dev/null
+++ b/meld/ui/pathlabel.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2019 Kai Willadsen <kai willadsen gmail com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+from gi.repository import Gdk, Gio, GObject, Gtk
+
+from meld.conf import _
+from meld.melddoc import open_files_external
+
+
+@Gtk.Template(resource_path='/org/gnome/meld/ui/path-label.ui')
+class PathLabel(Gtk.MenuButton):
+
+    __gtype_name__ = 'PathLabel'
+
+    full_path_label = Gtk.Template.Child()
+
+    custom_label = GObject.Property(type=str, nick='Custom label override')
+    gfile = GObject.Property(type=Gio.File, nick='GFile being displayed')
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.bind_property(
+            'gfile', self, 'label',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+            self.get_display_label,
+        )
+        self.bind_property(
+            'custom_label', self, 'label',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+            self.get_display_label,
+        )
+
+        action_group = Gio.SimpleActionGroup()
+
+        actions = (
+            ('copy-full-path', self.action_copy_full_path),
+            ('open-folder', self.action_open_folder),
+        )
+        for (name, callback) in actions:
+            action = Gio.SimpleAction.new(name, None)
+            action.connect('activate', callback)
+            action_group.add_action(action)
+
+        self.insert_action_group('widget', action_group)
+
+    def do_realize(self):
+        # As a workaround for pygobject#341, we delay this binding until
+        # realize, at which point the child object is correct.
+        self.bind_property(
+            'gfile', self.full_path_label, 'text',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+            self.get_display_path,
+        )
+
+        return Gtk.MenuButton.do_realize(self)
+
+    def get_display_label(self, binding, from_value) -> str:
+        if self.custom_label:
+            return self.custom_label
+        elif self.gfile:
+            # TODO: Ideally we'd do some cross-filename summarisation here
+            # instead of just showing the basename.
+            return self.gfile.get_basename()
+        else:
+            return _('Unnamed file')
+
+    def get_display_path(self, binding, from_value):
+        if from_value:
+            return from_value.get_parse_name()
+        return ''
+
+    def action_copy_full_path(self, *args):
+        if not self.gfile:
+            return
+
+        path = self.gfile.get_path() or self.gfile.get_uri()
+        clip = Gtk.Clipboard.get_default(Gdk.Display.get_default())
+        clip.set_text(path, -1)
+        clip.store()
+
+    def action_open_folder(self, *args):
+        if not self.gfile:
+            return
+
+        parent = self.gfile.get_parent()
+        if parent:
+            open_files_external(gfiles=[parent])
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6cbaa292..3e420962 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ meld/resources/ui/language-selector.ui
 meld/resources/ui/new-diff-tab.ui
 meld/resources/ui/notebook-label.ui
 meld/resources/ui/patch-dialog.ui
+meld/resources/ui/path-label.ui
 meld/resources/ui/preferences.ui
 meld/resources/ui/push-dialog.ui
 meld/resources/ui/recent-selector.ui
@@ -53,6 +54,7 @@ meld/ui/findbar.py
 meld/ui/historyentry.py
 meld/ui/msgarea.py
 meld/ui/notebooklabel.py
+meld/ui/pathlabel.py
 meld/ui/statusbar.py
 meld/ui/vcdialogs.py
 meld/vc/git.py


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