Merge branch 'master' into 'master'
Refactor some Tooltips See merge request gajim/gajim!180
This commit is contained in:
commit
fd7f302044
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.18.3 -->
|
<!-- Generated with glade 3.20.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.12"/>
|
<requires lib="gtk+" version="3.12"/>
|
||||||
<object class="GtkAccelGroup" id="accelgroup1"/>
|
<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-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="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="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"/>
|
<signal name="row-activated" handler="on_transfers_list_row_activated" swapped="no"/>
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
||||||
|
@ -247,6 +245,9 @@
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
<child internal-child="accessible">
|
<child internal-child="accessible">
|
||||||
<object class="AtkObject" id="file_transfers_window-atkobject">
|
<object class="AtkObject" id="file_transfers_window-atkobject">
|
||||||
<property name="AtkObject::accessible-name" translatable="yes">File Transfers</property>
|
<property name="AtkObject::accessible-name" translatable="yes">File Transfers</property>
|
||||||
|
|
|
@ -140,7 +140,12 @@ class FileTransfersWindow:
|
||||||
|
|
||||||
self.tree.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
|
self.tree.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
|
||||||
self.tree.get_selection().connect('changed', self.selection_changed)
|
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.tooltip = tooltips.FileTransfersTooltip()
|
||||||
|
|
||||||
self.file_transfers_menu = self.xml.get_object('file_transfers_menu')
|
self.file_transfers_menu = self.xml.get_object('file_transfers_menu')
|
||||||
self.open_folder_menuitem = self.xml.get_object('open_folder_menuitem')
|
self.open_folder_menuitem = self.xml.get_object('open_folder_menuitem')
|
||||||
self.cancel_menuitem = self.xml.get_object('cancel_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.remove_menuitem = self.xml.get_object('remove_menuitem')
|
||||||
self.xml.connect_signals(self)
|
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):
|
def find_transfer_by_jid(self, account, jid):
|
||||||
"""
|
"""
|
||||||
Find all transfers with peer 'jid' that belong to 'account'
|
Find all transfers with peer 'jid' that belong to 'account'
|
||||||
|
@ -301,9 +333,7 @@ class FileTransfersWindow:
|
||||||
def on_ok(widget):
|
def on_ok(widget):
|
||||||
file_dir = None
|
file_dir = None
|
||||||
files_path_list = dialog.get_filenames()
|
files_path_list = dialog.get_filenames()
|
||||||
text_buffer = desc_entry.get_buffer()
|
desc = desc_entry.get_text()
|
||||||
desc = text_buffer.get_text(text_buffer.get_start_iter(),
|
|
||||||
text_buffer.get_end_iter(), True)
|
|
||||||
for file_path in files_path_list:
|
for file_path in files_path_list:
|
||||||
if self.send_file(account, contact, file_path, desc) \
|
if self.send_file(account, contact, file_path, desc) \
|
||||||
and file_dir is None:
|
and file_dir is None:
|
||||||
|
@ -721,7 +751,6 @@ class FileTransfersWindow:
|
||||||
"""
|
"""
|
||||||
Add new transfer to FT window and show the FT window
|
Add new transfer to FT window and show the FT window
|
||||||
"""
|
"""
|
||||||
self.on_transfers_list_leave_notify_event(None)
|
|
||||||
if file_props is None:
|
if file_props is None:
|
||||||
return
|
return
|
||||||
file_props.elapsed_time = 0
|
file_props.elapsed_time = 0
|
||||||
|
@ -752,45 +781,6 @@ class FileTransfersWindow:
|
||||||
self.set_cleanup_sensitivity()
|
self.set_cleanup_sensitivity()
|
||||||
self.window.show_all()
|
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):
|
def on_transfers_list_row_activated(self, widget, path, col):
|
||||||
# try to open the containing folder
|
# try to open the containing folder
|
||||||
self.on_open_folder_menuitem_activate(widget)
|
self.on_open_folder_menuitem_activate(widget)
|
||||||
|
@ -954,37 +944,11 @@ class FileTransfersWindow:
|
||||||
con.disconnect_transfer(file_props)
|
con.disconnect_transfer(file_props)
|
||||||
self.set_status(file_props, 'stop')
|
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):
|
def on_notify_ft_complete_checkbox_toggled(self, widget):
|
||||||
app.config.set('notify_on_file_complete',
|
app.config.set('notify_on_file_complete',
|
||||||
widget.get_active())
|
widget.get_active())
|
||||||
|
|
||||||
def on_file_transfers_dialog_delete_event(self, widget, event):
|
def on_file_transfers_dialog_delete_event(self, widget, event):
|
||||||
self.on_transfers_list_leave_notify_event(widget, None)
|
|
||||||
self.window.hide()
|
self.window.hide()
|
||||||
return True # do NOT destory window
|
return True # do NOT destory window
|
||||||
|
|
||||||
|
@ -1006,7 +970,6 @@ class FileTransfersWindow:
|
||||||
"""
|
"""
|
||||||
When a key is pressed in the treeviews
|
When a key is pressed in the treeviews
|
||||||
"""
|
"""
|
||||||
self.tooltip.hide_tooltip()
|
|
||||||
iter_ = None
|
iter_ = None
|
||||||
try:
|
try:
|
||||||
iter_ = self.tree.get_selection().get_selected()[1]
|
iter_ = self.tree.get_selection().get_selected()[1]
|
||||||
|
@ -1024,7 +987,6 @@ class FileTransfersWindow:
|
||||||
|
|
||||||
def on_transfers_list_button_release_event(self, widget, event):
|
def on_transfers_list_button_release_event(self, widget, event):
|
||||||
# hide tooltip, no matter the button is pressed
|
# hide tooltip, no matter the button is pressed
|
||||||
self.tooltip.hide_tooltip()
|
|
||||||
path = None
|
path = None
|
||||||
try:
|
try:
|
||||||
path = self.tree.get_path_at_pos(int(event.x), int(event.y))[0]
|
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):
|
def on_transfers_list_button_press_event(self, widget, event):
|
||||||
# hide tooltip, no matter the button is pressed
|
# hide tooltip, no matter the button is pressed
|
||||||
self.tooltip.hide_tooltip()
|
|
||||||
path, iter_ = None, None
|
path, iter_ = None, None
|
||||||
try:
|
try:
|
||||||
path = self.tree.get_path_at_pos(int(event.x), int(event.y))[0]
|
path = self.tree.get_path_at_pos(int(event.x), int(event.y))[0]
|
||||||
|
|
|
@ -303,7 +303,6 @@ class GroupchatControl(ChatControlBase):
|
||||||
formattings_button = self.xml.get_object('formattings_button')
|
formattings_button = self.xml.get_object('formattings_button')
|
||||||
formattings_button.set_sensitive(False)
|
formattings_button.set_sensitive(False)
|
||||||
|
|
||||||
self.current_tooltip = None
|
|
||||||
if parent_win is not None:
|
if parent_win is not None:
|
||||||
# On AutoJoin with minimize Groupchats are created without parent
|
# On AutoJoin with minimize Groupchats are created without parent
|
||||||
# Tooltip Window and Actions have to be created with parent
|
# Tooltip Window and Actions have to be created with parent
|
||||||
|
@ -474,6 +473,9 @@ class GroupchatControl(ChatControlBase):
|
||||||
self.banner_actionbar.pack_end(self.hide_roster_button)
|
self.banner_actionbar.pack_end(self.hide_roster_button)
|
||||||
self.banner_actionbar.pack_start(self.subject_button)
|
self.banner_actionbar.pack_start(self.subject_button)
|
||||||
|
|
||||||
|
# GC Roster tooltip
|
||||||
|
self.gc_tooltip = tooltips.GCTooltip()
|
||||||
|
|
||||||
self.control_menu = gui_menu_builder.get_groupchat_menu(self.control_id)
|
self.control_menu = gui_menu_builder.get_groupchat_menu(self.control_id)
|
||||||
|
|
||||||
app.ged.register_event_handler('gc-presence-received', ged.GUI1,
|
app.ged.register_event_handler('gc-presence-received', ged.GUI1,
|
||||||
|
@ -714,8 +716,6 @@ class GroupchatControl(ChatControlBase):
|
||||||
if widget.get_tooltip_window():
|
if widget.get_tooltip_window():
|
||||||
return
|
return
|
||||||
widget.set_has_tooltip(True)
|
widget.set_has_tooltip(True)
|
||||||
widget.set_tooltip_window(tooltips.GCTooltip(
|
|
||||||
self.account, self.parent_win.window))
|
|
||||||
id_ = widget.connect('query-tooltip', self.query_tooltip)
|
id_ = widget.connect('query-tooltip', self.query_tooltip)
|
||||||
self.handlers[id_] = widget
|
self.handlers[id_] = widget
|
||||||
|
|
||||||
|
@ -723,41 +723,35 @@ class GroupchatControl(ChatControlBase):
|
||||||
try:
|
try:
|
||||||
row = self.list_treeview.get_path_at_pos(x_pos, y_pos)[0]
|
row = self.list_treeview.get_path_at_pos(x_pos, y_pos)[0]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
self.gc_tooltip.clear_tooltip()
|
||||||
return False
|
return False
|
||||||
if not row:
|
if not row:
|
||||||
|
self.gc_tooltip.clear_tooltip()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
iter_ = None
|
iter_ = None
|
||||||
try:
|
try:
|
||||||
iter_ = self.model.get_iter(row)
|
iter_ = self.model.get_iter(row)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
self.gc_tooltip.clear_tooltip()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
typ = self.model[iter_][Column.TYPE]
|
typ = self.model[iter_][Column.TYPE]
|
||||||
nick = self.model[iter_][Column.NICK]
|
nick = self.model[iter_][Column.NICK]
|
||||||
|
|
||||||
if typ != 'contact':
|
if typ != 'contact':
|
||||||
|
self.gc_tooltip.clear_tooltip()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.current_tooltip != row:
|
|
||||||
# If the row changes we hide the current tooltip
|
|
||||||
self.current_tooltip = row
|
|
||||||
return False
|
|
||||||
|
|
||||||
tooltip = widget.get_tooltip_window()
|
|
||||||
|
|
||||||
if tooltip.row == row:
|
|
||||||
# We already populated the window with the row data
|
|
||||||
return True
|
|
||||||
tooltip.row = row
|
|
||||||
|
|
||||||
contact = app.contacts.get_gc_contact(
|
contact = app.contacts.get_gc_contact(
|
||||||
self.account, self.room_jid, nick)
|
self.account, self.room_jid, nick)
|
||||||
if not contact:
|
if not contact:
|
||||||
|
self.gc_tooltip.clear_tooltip()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tooltip.populate(contact)
|
value, widget = self.gc_tooltip.get_tooltip(contact)
|
||||||
return True
|
tooltip.set_custom(widget)
|
||||||
|
return value
|
||||||
|
|
||||||
def fill_column(self, col):
|
def fill_column(self, col):
|
||||||
for rend in self.renderers_list:
|
for rend in self.renderers_list:
|
||||||
|
|
|
@ -1102,8 +1102,6 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
htmlview = ConversationTextview(None)
|
htmlview = ConversationTextview(None)
|
||||||
|
|
||||||
tooltip = tooltips.BaseTooltip()
|
|
||||||
|
|
||||||
def on_textview_motion_notify_event(widget, event):
|
def on_textview_motion_notify_event(widget, event):
|
||||||
"""
|
"""
|
||||||
Change the cursor to a hand when we are over a mail or an url
|
Change the cursor to a hand when we are over a mail or an url
|
||||||
|
@ -1129,17 +1127,6 @@ if __name__ == '__main__':
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#if line_tooltip.timeout != 0:
|
|
||||||
# Check if we should hide the line tooltip
|
|
||||||
# if not over_line:
|
|
||||||
# line_tooltip.hide_tooltip()
|
|
||||||
#if over_line and not line_tooltip.win:
|
|
||||||
# line_tooltip.timeout = GLib.timeout_add(500,
|
|
||||||
# show_line_tooltip)
|
|
||||||
# htmlview.tv.get_window(Gtk.TextWindowType.TEXT).set_cursor(
|
|
||||||
# gtkgui_helpers.get_cursor('LEFT_PTR'))
|
|
||||||
# change_cursor = tag
|
|
||||||
|
|
||||||
htmlview.tv.connect('motion_notify_event', on_textview_motion_notify_event)
|
htmlview.tv.connect('motion_notify_event', on_textview_motion_notify_event)
|
||||||
|
|
||||||
def handler(texttag, widget, event, iter_, kind):
|
def handler(texttag, widget, event, iter_, kind):
|
||||||
|
|
|
@ -102,6 +102,15 @@ class MessageTextView(Gtk.TextView):
|
||||||
text = buf.get_text(start, end, True)
|
text = buf.get_text(start, end, True)
|
||||||
return text != self.PLACEHOLDER and text != ''
|
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):
|
def is_placeholder(self):
|
||||||
buf = self.get_buffer()
|
buf = self.get_buffer()
|
||||||
start, end = buf.get_bounds()
|
start, end = buf.get_bounds()
|
||||||
|
|
|
@ -104,8 +104,7 @@ class StatusIcon:
|
||||||
self.make_menu(event_button, event_time)
|
self.make_menu(event_button, event_time)
|
||||||
|
|
||||||
def on_status_icon_query_tooltip(self, widget, x, y, keyboard_mode, tooltip):
|
def on_status_icon_query_tooltip(self, widget, x, y, keyboard_mode, tooltip):
|
||||||
self.tooltip.populate()
|
tooltip.set_custom(self.tooltip.get_tooltip())
|
||||||
tooltip.set_custom(self.tooltip.hbox)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def hide_icon(self):
|
def hide_icon(self):
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
##
|
##
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
from gi.repository import Pango
|
from gi.repository import Pango
|
||||||
import os
|
|
||||||
import time
|
|
||||||
from datetime import datetime
|
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
from gajim import gtkgui_helpers
|
from gajim import gtkgui_helpers
|
||||||
from gajim.common.const import AvatarSize
|
from gajim.common.const import AvatarSize
|
||||||
|
@ -43,147 +43,6 @@ from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.i18n import Q_
|
from gajim.common.i18n import Q_
|
||||||
|
|
||||||
class BaseTooltip:
|
|
||||||
"""
|
|
||||||
Base Tooltip class
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
tooltip = BaseTooltip()
|
|
||||||
....
|
|
||||||
tooltip.show_tooltip(data, widget_height, widget_y_position)
|
|
||||||
....
|
|
||||||
if tooltip.timeout != 0:
|
|
||||||
tooltip.hide_tooltip()
|
|
||||||
|
|
||||||
* data - the text to be displayed (extenders override this argument and
|
|
||||||
display more complex contents)
|
|
||||||
* widget_height - the height of the widget on which we want to show tooltip
|
|
||||||
* widget_y_position - the vertical position of the widget on the screen
|
|
||||||
|
|
||||||
Tooltip is displayed aligned centered to the mouse poiner and 4px below the widget.
|
|
||||||
In case tooltip goes below the visible area it is shown above the widget.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.timeout = 0
|
|
||||||
self.preferred_position = [0, 0]
|
|
||||||
self.win = None
|
|
||||||
self.id = None
|
|
||||||
self.cur_data = None
|
|
||||||
self.shown = False
|
|
||||||
self.position_computed = False
|
|
||||||
|
|
||||||
def populate(self, data):
|
|
||||||
"""
|
|
||||||
This method must be overriden by all extenders. This is the most simple
|
|
||||||
implementation: show data as value of a label
|
|
||||||
"""
|
|
||||||
self.create_window()
|
|
||||||
self.win.add(Gtk.Label(label=data))
|
|
||||||
|
|
||||||
def create_window(self):
|
|
||||||
"""
|
|
||||||
Create a popup window each time tooltip is requested
|
|
||||||
"""
|
|
||||||
self.win = Gtk.Window.new(Gtk.WindowType.POPUP)
|
|
||||||
self.win.set_title('tooltip')
|
|
||||||
self.win.set_border_width(3)
|
|
||||||
self.win.set_resizable(False)
|
|
||||||
self.win.set_name('gtk-tooltips')
|
|
||||||
self.win.set_type_hint(Gdk.WindowTypeHint.TOOLTIP)
|
|
||||||
|
|
||||||
self.win.set_events(Gdk.EventMask.POINTER_MOTION_MASK)
|
|
||||||
self.win.connect('size-allocate', self.on_size_allocate)
|
|
||||||
self.win.connect('motion-notify-event', self.motion_notify_event)
|
|
||||||
self.screen = self.win.get_screen()
|
|
||||||
|
|
||||||
def _get_icon_name_for_tooltip(self, contact):
|
|
||||||
"""
|
|
||||||
Helper function used for tooltip contacts/acounts
|
|
||||||
|
|
||||||
Tooltip on account has fake contact with sub == '', in this case we show
|
|
||||||
real status of the account
|
|
||||||
"""
|
|
||||||
if contact.ask == 'subscribe':
|
|
||||||
return 'requested'
|
|
||||||
elif contact.sub in ('both', 'to', ''):
|
|
||||||
return contact.show
|
|
||||||
return 'not in roster'
|
|
||||||
|
|
||||||
def motion_notify_event(self, widget, event):
|
|
||||||
GLib.idle_add(self.hide_tooltip)
|
|
||||||
|
|
||||||
def on_size_allocate(self, widget, rect):
|
|
||||||
if not self.position_computed:
|
|
||||||
half_width = rect.width / 2 + 1
|
|
||||||
if self.preferred_position[1] + rect.height > \
|
|
||||||
self.screen.get_height():
|
|
||||||
# flip tooltip up
|
|
||||||
self.preferred_position[1] -= rect.height + self.widget_height \
|
|
||||||
+ 8
|
|
||||||
if self.preferred_position[1] < 0:
|
|
||||||
self.preferred_position[1] = self.screen.get_height() - \
|
|
||||||
rect.height - 2
|
|
||||||
|
|
||||||
if self.preferred_position[0] + rect.width + 7 < \
|
|
||||||
self.screen.get_width():
|
|
||||||
self.preferred_position[0] = self.preferred_position[0]\
|
|
||||||
+ 7
|
|
||||||
else:
|
|
||||||
self.preferred_position[0] = self.preferred_position[0]\
|
|
||||||
- rect.width - 7
|
|
||||||
self.win.move(self.preferred_position[0],
|
|
||||||
self.preferred_position[1])
|
|
||||||
return
|
|
||||||
if self.preferred_position[0] < half_width:
|
|
||||||
self.preferred_position[0] = 0
|
|
||||||
elif self.preferred_position[0] + rect.width > \
|
|
||||||
self.screen.get_width() + half_width:
|
|
||||||
self.preferred_position[0] = self.screen.get_width() - \
|
|
||||||
rect.width
|
|
||||||
else:
|
|
||||||
self.preferred_position[0] -= half_width
|
|
||||||
self.position_computed = True
|
|
||||||
self.win.move(self.preferred_position[0], self.preferred_position[1])
|
|
||||||
|
|
||||||
def show_tooltip(self, data, widget_height, widget_y_position):
|
|
||||||
"""
|
|
||||||
Show tooltip on widget
|
|
||||||
|
|
||||||
Data contains needed data for tooltip contents.
|
|
||||||
widget_height is the height of the widget on which we show the tooltip.
|
|
||||||
widget_y_position is vertical position of the widget on the screen.
|
|
||||||
"""
|
|
||||||
if self.shown:
|
|
||||||
return
|
|
||||||
self.position_computed = False
|
|
||||||
self.cur_data = data
|
|
||||||
# set tooltip contents
|
|
||||||
self.populate(data)
|
|
||||||
|
|
||||||
# get the X position of mouse pointer on the screen
|
|
||||||
pointer_x = self.screen.get_display().get_device_manager().\
|
|
||||||
get_client_pointer().get_position()[1]
|
|
||||||
|
|
||||||
# get the prefered X position of the tooltip on the screen in case this position is >
|
|
||||||
# than the height of the screen, tooltip will be shown above the widget
|
|
||||||
preferred_y = widget_y_position + widget_height + 4
|
|
||||||
|
|
||||||
self.preferred_position = [pointer_x, preferred_y]
|
|
||||||
self.widget_height = widget_height
|
|
||||||
self.win.show_all()
|
|
||||||
self.shown = True
|
|
||||||
|
|
||||||
def hide_tooltip(self):
|
|
||||||
if self.timeout > 0:
|
|
||||||
GLib.source_remove(self.timeout)
|
|
||||||
self.timeout = 0
|
|
||||||
if self.win:
|
|
||||||
self.win.destroy()
|
|
||||||
self.win = None
|
|
||||||
self.id = None
|
|
||||||
self.cur_data = None
|
|
||||||
self.shown = False
|
|
||||||
|
|
||||||
class StatusTable:
|
class StatusTable:
|
||||||
"""
|
"""
|
||||||
|
@ -263,13 +122,13 @@ class StatusTable:
|
||||||
self.table.attach(lock_image, 4, self.current_row, 1, 1)
|
self.table.attach(lock_image, 4, self.current_row, 1, 1)
|
||||||
self.current_row += 1
|
self.current_row += 1
|
||||||
|
|
||||||
class NotificationAreaTooltip(BaseTooltip, StatusTable):
|
|
||||||
|
class NotificationAreaTooltip(StatusTable):
|
||||||
"""
|
"""
|
||||||
Tooltip that is shown in the notification area
|
Tooltip that is shown in the notification area
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
BaseTooltip.__init__(self)
|
|
||||||
StatusTable.__init__(self)
|
StatusTable.__init__(self)
|
||||||
|
|
||||||
def fill_table_with_accounts(self, accounts):
|
def fill_table_with_accounts(self, accounts):
|
||||||
|
@ -297,8 +156,7 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable):
|
||||||
for line in acct['event_lines']:
|
for line in acct['event_lines']:
|
||||||
self.add_text_row(' ' + line, 1)
|
self.add_text_row(' ' + line, 1)
|
||||||
|
|
||||||
def populate(self, data=''):
|
def get_tooltip(self):
|
||||||
self.create_window()
|
|
||||||
self.create_table()
|
self.create_table()
|
||||||
|
|
||||||
accounts = helpers.get_notification_icon_tooltip_dict()
|
accounts = helpers.get_notification_icon_tooltip_dict()
|
||||||
|
@ -308,40 +166,43 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable):
|
||||||
|
|
||||||
self.hbox.add(self.table)
|
self.hbox.add(self.table)
|
||||||
self.hbox.show_all()
|
self.hbox.show_all()
|
||||||
|
return self.hbox
|
||||||
|
|
||||||
class GCTooltip(Gtk.Window):
|
|
||||||
|
class GCTooltip():
|
||||||
# pylint: disable=E1101
|
# pylint: disable=E1101
|
||||||
def __init__(self, account, parent):
|
def __init__(self):
|
||||||
Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP, transient_for=parent)
|
self.contact = None
|
||||||
self.account = account
|
|
||||||
self.row = None
|
|
||||||
self.set_title('tooltip')
|
|
||||||
self.set_border_width(3)
|
|
||||||
self.set_resizable(False)
|
|
||||||
self.set_name('gtk-tooltips')
|
|
||||||
self.set_type_hint(Gdk.WindowTypeHint.TOOLTIP)
|
|
||||||
|
|
||||||
self.xml = gtkgui_helpers.get_gtk_builder('tooltip_gc_contact.ui')
|
self.xml = gtkgui_helpers.get_gtk_builder('tooltip_gc_contact.ui')
|
||||||
for name in ('nick', 'status', 'jid', 'user_show', 'fillelement',
|
for name in ('nick', 'status', 'jid', 'user_show', 'fillelement',
|
||||||
'resource', 'affiliation', 'avatar', 'resource_label',
|
'resource', 'affiliation', 'avatar', 'resource_label',
|
||||||
'jid_label', 'tooltip_grid'):
|
'jid_label', 'tooltip_grid'):
|
||||||
setattr(self, name, self.xml.get_object(name))
|
setattr(self, name, self.xml.get_object(name))
|
||||||
|
|
||||||
self.add(self.tooltip_grid)
|
|
||||||
self.tooltip_grid.show()
|
|
||||||
|
|
||||||
def clear_tooltip(self):
|
def clear_tooltip(self):
|
||||||
|
self.contact = None
|
||||||
|
|
||||||
|
def get_tooltip(self, contact):
|
||||||
|
if self.contact == contact:
|
||||||
|
return True, self.tooltip_grid
|
||||||
|
|
||||||
|
self._populate_grid(contact)
|
||||||
|
self.contact = contact
|
||||||
|
return False, self.tooltip_grid
|
||||||
|
|
||||||
|
def _hide_grid_childs(self):
|
||||||
"""
|
"""
|
||||||
Hide all Elements of the Tooltip Grid
|
Hide all Elements of the Tooltip Grid
|
||||||
"""
|
"""
|
||||||
for child in self.tooltip_grid.get_children():
|
for child in self.tooltip_grid.get_children():
|
||||||
child.hide()
|
child.hide()
|
||||||
|
|
||||||
def populate(self, contact):
|
def _populate_grid(self, contact):
|
||||||
"""
|
"""
|
||||||
Populate the Tooltip Grid with data of from the contact
|
Populate the Tooltip Grid with data of from the contact
|
||||||
"""
|
"""
|
||||||
self.clear_tooltip()
|
self._hide_grid_childs()
|
||||||
|
|
||||||
self.nick.set_text(contact.get_shown_name())
|
self.nick.set_text(contact.get_shown_name())
|
||||||
self.nick.show()
|
self.nick.show()
|
||||||
|
@ -750,19 +611,28 @@ class RosterTooltip(Gtk.Window, StatusTable):
|
||||||
return 'not in roster'
|
return 'not in roster'
|
||||||
|
|
||||||
|
|
||||||
class FileTransfersTooltip(BaseTooltip):
|
class FileTransfersTooltip():
|
||||||
"""
|
|
||||||
Tooltip that is shown in the notification area
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
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 = Gtk.Table(2, 1)
|
||||||
ft_table.set_property('column-spacing', 2)
|
ft_table.set_property('column-spacing', 2)
|
||||||
current_row = 1
|
current_row = 1
|
||||||
self.create_window()
|
|
||||||
properties = []
|
properties = []
|
||||||
name = file_props.name
|
name = file_props.name
|
||||||
if file_props.type_ == 'r':
|
if file_props.type_ == 'r':
|
||||||
|
@ -794,18 +664,18 @@ class FileTransfersTooltip(BaseTooltip):
|
||||||
status = ''
|
status = ''
|
||||||
if file_props.started:
|
if file_props.started:
|
||||||
status = _('Not started')
|
status = _('Not started')
|
||||||
if file_props.stopped == True:
|
if file_props.stopped:
|
||||||
status = _('Stopped')
|
status = _('Stopped')
|
||||||
elif file_props.completed:
|
elif file_props.completed:
|
||||||
status = _('Completed')
|
status = _('Completed')
|
||||||
elif file_props.connected == False:
|
elif not file_props.connected:
|
||||||
if file_props.completed:
|
if file_props.completed:
|
||||||
status = _('Completed')
|
status = _('Completed')
|
||||||
else:
|
else:
|
||||||
if file_props.paused == True:
|
if file_props.paused:
|
||||||
status = Q_('?transfer status:Paused')
|
status = Q_('?transfer status:Paused')
|
||||||
elif file_props.stalled == True:
|
elif file_props.stalled:
|
||||||
#stalled is not paused. it is like 'frozen' it stopped alone
|
# stalled is not paused. it is like 'frozen' it stopped alone
|
||||||
status = _('Stalled')
|
status = _('Stalled')
|
||||||
else:
|
else:
|
||||||
status = _('Transferring')
|
status = _('Transferring')
|
||||||
|
@ -832,7 +702,8 @@ class FileTransfersTooltip(BaseTooltip):
|
||||||
ft_table.attach(label, 2, 3, current_row, current_row + 1,
|
ft_table.attach(label, 2, 3, current_row, current_row + 1,
|
||||||
Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0)
|
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):
|
def colorize_status(status):
|
||||||
|
|
Loading…
Reference in New Issue