From 9db9e69c3595fc0517494b22cc247238d3f066eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <forenjunkie@chello.at>
Date: Fri, 22 Dec 2017 20:55:00 +0100
Subject: [PATCH] Refactor FileTransferWindow tooltip

---
 gajim/data/gui/filetransfers.ui |   7 ++-
 gajim/filetransfers_window.py   | 105 ++++++++++----------------------
 gajim/message_textview.py       |   9 +++
 gajim/tooltips.py               |  38 +++++++-----
 4 files changed, 70 insertions(+), 89 deletions(-)

diff --git a/gajim/data/gui/filetransfers.ui b/gajim/data/gui/filetransfers.ui
index bde4547ce5..2fe11bf4d4 100644
--- a/gajim/data/gui/filetransfers.ui
+++ b/gajim/data/gui/filetransfers.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.20.1 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <object class="GtkAccelGroup" id="accelgroup1"/>
@@ -101,8 +101,6 @@
                 <signal name="button-press-event" handler="on_transfers_list_button_press_event" swapped="no"/>
                 <signal name="button-release-event" handler="on_transfers_list_button_release_event" swapped="no"/>
                 <signal name="key-press-event" handler="on_transfers_list_key_press_event" swapped="no"/>
-                <signal name="leave-notify-event" handler="on_transfers_list_leave_notify_event" swapped="no"/>
-                <signal name="motion-notify-event" handler="on_transfers_list_motion_notify_event" swapped="no"/>
                 <signal name="row-activated" handler="on_transfers_list_row_activated" swapped="no"/>
                 <child internal-child="selection">
                   <object class="GtkTreeSelection" id="treeview-selection1"/>
@@ -247,6 +245,9 @@
         </child>
       </object>
     </child>
+    <child type="titlebar">
+      <placeholder/>
+    </child>
     <child internal-child="accessible">
       <object class="AtkObject" id="file_transfers_window-atkobject">
         <property name="AtkObject::accessible-name" translatable="yes">File Transfers</property>
diff --git a/gajim/filetransfers_window.py b/gajim/filetransfers_window.py
index d78617047b..2935eaac24 100644
--- a/gajim/filetransfers_window.py
+++ b/gajim/filetransfers_window.py
@@ -140,7 +140,12 @@ class FileTransfersWindow:
 
         self.tree.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
         self.tree.get_selection().connect('changed', self.selection_changed)
+
+        # Tooltip
+        self.tree.connect('query-tooltip', self._query_tooltip)
+        self.tree.set_has_tooltip(True)
         self.tooltip = tooltips.FileTransfersTooltip()
+
         self.file_transfers_menu = self.xml.get_object('file_transfers_menu')
         self.open_folder_menuitem = self.xml.get_object('open_folder_menuitem')
         self.cancel_menuitem = self.xml.get_object('cancel_menuitem')
@@ -149,6 +154,33 @@ class FileTransfersWindow:
         self.remove_menuitem = self.xml.get_object('remove_menuitem')
         self.xml.connect_signals(self)
 
+    def _query_tooltip(self, widget, x_pos, y_pos, keyboard_mode, tooltip):
+        try:
+            x_pos, y_pos = widget.convert_widget_to_bin_window_coords(
+                x_pos, y_pos)
+            row = widget.get_path_at_pos(x_pos, y_pos)[0]
+        except TypeError:
+            self.tooltip.clear_tooltip()
+            return False
+        if not row:
+            self.tooltip.clear_tooltip()
+            return False
+
+        iter_ = None
+        try:
+            model = widget.get_model()
+            iter_ = model.get_iter(row)
+        except Exception:
+            self.tooltip.clear_tooltip()
+            return False
+
+        sid = self.model[iter_][Column.SID]
+        file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
+
+        value, widget = self.tooltip.get_tooltip(file_props, sid)
+        tooltip.set_custom(widget)
+        return value
+
     def find_transfer_by_jid(self, account, jid):
         """
         Find all transfers with peer 'jid' that belong to 'account'
@@ -301,9 +333,7 @@ class FileTransfersWindow:
         def on_ok(widget):
             file_dir = None
             files_path_list = dialog.get_filenames()
-            text_buffer = desc_entry.get_buffer()
-            desc = text_buffer.get_text(text_buffer.get_start_iter(),
-                text_buffer.get_end_iter(), True)
+            desc = desc_entry.get_text()
             for file_path in files_path_list:
                 if self.send_file(account, contact, file_path, desc) \
                 and file_dir is None:
@@ -721,7 +751,6 @@ class FileTransfersWindow:
         """
         Add new transfer to FT window and show the FT window
         """
-        self.on_transfers_list_leave_notify_event(None)
         if file_props is None:
             return
         file_props.elapsed_time = 0
@@ -752,45 +781,6 @@ class FileTransfersWindow:
         self.set_cleanup_sensitivity()
         self.window.show_all()
 
-    def on_transfers_list_motion_notify_event(self, widget, event):
-        w = self.tree.get_window()
-        device = w.get_display().get_device_manager().get_client_pointer()
-        pointer = w.get_device_position(device)
-        props = widget.get_path_at_pos(int(event.x), int(event.y))
-        self.height_diff = pointer[2] - int(event.y)
-        if self.tooltip.timeout > 0 or self.tooltip.shown:
-            if not props or self.tooltip.id != props[0]:
-                self.tooltip.hide_tooltip()
-        if props:
-            row = props[0]
-            iter_ = None
-            try:
-                iter_ = self.model.get_iter(row)
-            except Exception:
-                self.tooltip.hide_tooltip()
-                return
-            sid = self.model[iter_][Column.SID]
-            file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
-            if file_props is not None:
-                if self.tooltip.timeout == 0 or self.tooltip.id != props[0]:
-                    self.tooltip.id = row
-                    self.tooltip.timeout = GLib.timeout_add(500,
-                        self.show_tooltip, widget)
-
-    def on_transfers_list_leave_notify_event(self, widget=None, event=None):
-        if event is not None:
-            self.height_diff = int(event.y)
-        elif self.height_diff is 0:
-            return
-        w = self.tree.get_window()
-        device = w.get_display().get_device_manager().get_client_pointer()
-        pointer = w.get_device_position(device)
-        props = self.tree.get_path_at_pos(pointer[1],
-            pointer[2] - self.height_diff)
-        if self.tooltip.timeout > 0 or self.tooltip.shown:
-            if not props or self.tooltip.id == props[0]:
-                self.tooltip.hide_tooltip()
-
     def on_transfers_list_row_activated(self, widget, path, col):
         # try to open the containing folder
         self.on_open_folder_menuitem_activate(widget)
@@ -954,37 +944,11 @@ class FileTransfersWindow:
         con.disconnect_transfer(file_props)
         self.set_status(file_props, 'stop')
 
-    def show_tooltip(self, widget):
-        self.tooltip.timeout = 0
-        if self.height_diff == 0:
-            self.tooltip.hide_tooltip()
-            return
-        w = self.tree.get_window()
-        device = w.get_display().get_device_manager().get_client_pointer()
-        pointer = w.get_device_position(device)
-        props = self.tree.get_path_at_pos(pointer[1],
-            pointer[2] - self.height_diff)
-        # check if the current pointer is at the same path
-        # as it was before setting the timeout
-        if props and self.tooltip.id == props[0]:
-            iter_ = self.model.get_iter(props[0])
-            sid = self.model[iter_][Column.SID]
-            file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
-            # bounding rectangle of coordinates for the cell within the treeview
-            rect = self.tree.get_cell_area(props[0], props[1])
-            # position of the treeview on the screen
-            position = widget.get_window().get_origin()[1:]
-            self.tooltip.show_tooltip(file_props, rect.height,
-                position[1] + rect.y + self.height_diff)
-        else:
-            self.tooltip.hide_tooltip()
-
     def on_notify_ft_complete_checkbox_toggled(self, widget):
         app.config.set('notify_on_file_complete',
                 widget.get_active())
 
     def on_file_transfers_dialog_delete_event(self, widget, event):
-        self.on_transfers_list_leave_notify_event(widget, None)
         self.window.hide()
         return True # do NOT destory window
 
@@ -1006,7 +970,6 @@ class FileTransfersWindow:
         """
         When a key is pressed in the treeviews
         """
-        self.tooltip.hide_tooltip()
         iter_ = None
         try:
             iter_ = self.tree.get_selection().get_selected()[1]
@@ -1024,7 +987,6 @@ class FileTransfersWindow:
 
     def on_transfers_list_button_release_event(self, widget, event):
         # hide tooltip, no matter the button is pressed
-        self.tooltip.hide_tooltip()
         path = None
         try:
             path = self.tree.get_path_at_pos(int(event.x), int(event.y))[0]
@@ -1037,7 +999,6 @@ class FileTransfersWindow:
 
     def on_transfers_list_button_press_event(self, widget, event):
         # hide tooltip, no matter the button is pressed
-        self.tooltip.hide_tooltip()
         path, iter_ = None, None
         try:
             path = self.tree.get_path_at_pos(int(event.x), int(event.y))[0]
diff --git a/gajim/message_textview.py b/gajim/message_textview.py
index f76fdc603f..57b938a081 100644
--- a/gajim/message_textview.py
+++ b/gajim/message_textview.py
@@ -102,6 +102,15 @@ class MessageTextView(Gtk.TextView):
         text = buf.get_text(start, end, True)
         return text != self.PLACEHOLDER and text != ''
 
+    def get_text(self):
+        # gets the text if its not PLACEHOLDER
+        buf = self.get_buffer()
+        start, end = buf.get_bounds()
+        text = self.get_buffer().get_text(start, end, True)
+        if text == self.PLACEHOLDER:
+            return ''
+        return text
+
     def is_placeholder(self):
         buf = self.get_buffer()
         start, end = buf.get_bounds()
diff --git a/gajim/tooltips.py b/gajim/tooltips.py
index bd8482d342..a138b26d97 100644
--- a/gajim/tooltips.py
+++ b/gajim/tooltips.py
@@ -750,19 +750,28 @@ class RosterTooltip(Gtk.Window, StatusTable):
         return 'not in roster'
 
 
-class FileTransfersTooltip(BaseTooltip):
-    """
-    Tooltip that is shown in the notification area
-    """
-
+class FileTransfersTooltip():
     def __init__(self):
-        BaseTooltip.__init__(self)
+        self.sid = None
+        self.widget = None
 
-    def populate(self, file_props):
+    def clear_tooltip(self):
+        self.sid = None
+        self.widget = None
+
+    def get_tooltip(self, file_props, sid):
+        if self.sid == sid:
+            return True, self.widget
+
+        self.widget = self._create_tooltip(file_props, sid)
+        self.sid = sid
+        return False, self.widget
+
+    @staticmethod
+    def _create_tooltip(file_props, sid):
         ft_table = Gtk.Table(2, 1)
         ft_table.set_property('column-spacing', 2)
         current_row = 1
-        self.create_window()
         properties = []
         name = file_props.name
         if file_props.type_ == 'r':
@@ -794,18 +803,18 @@ class FileTransfersTooltip(BaseTooltip):
         status = ''
         if file_props.started:
             status = _('Not started')
-        if file_props.stopped == True:
+        if file_props.stopped:
             status = _('Stopped')
         elif file_props.completed:
             status = _('Completed')
-        elif file_props.connected == False:
+        elif not file_props.connected:
             if file_props.completed:
                 status = _('Completed')
             else:
-                if file_props.paused == True:
+                if file_props.paused:
                     status = Q_('?transfer status:Paused')
-                elif file_props.stalled == True:
-                    #stalled is not paused. it is like 'frozen' it stopped alone
+                elif file_props.stalled:
+                    # stalled is not paused. it is like 'frozen' it stopped alone
                     status = _('Stalled')
                 else:
                     status = _('Transferring')
@@ -832,7 +841,8 @@ class FileTransfersTooltip(BaseTooltip):
             ft_table.attach(label, 2, 3, current_row, current_row + 1,
                     Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0)
 
-        self.win.add(ft_table)
+        ft_table.show_all()
+        return ft_table
 
 
 def colorize_status(status):
-- 
GitLab