Philipp Hörist pushed to branch master at gajim / gajim
Commits: 2636e344 by Philipp Hörist at 2018-05-20T01:28:12+02:00 Refactor avatar publishing
- Publish avatars with a size of 200x200 - Add AvatarSize.PUBLISH so we can easily change it in the future - Dont upscale small avatars on publish - Use surfaces for displaying the avatar in ProfileWindow and VcardWindow because this scales correctly on HiDPI screens
- - - - - 28192328 by Philipp Hörist at 2018-05-20T01:28:12+02:00 Fix AvatarChooserDialog not beeing native
Setting mimetypes forces non-native dialogs
- - - - - 848cdc4a by Philipp Hörist at 2018-05-20T01:28:12+02:00 ProfileWindow: Remove redundant menu entry
- - - - -
8 changed files:
- gajim/common/const.py - gajim/filechoosers.py - gajim/groupchat_control.py - gajim/gtkgui_helpers.py - gajim/gui_interface.py - gajim/profile_window.py - gajim/remote_control.py - gajim/vcard.py
Changes:
===================================== gajim/common/const.py ===================================== --- a/gajim/common/const.py +++ b/gajim/common/const.py @@ -33,9 +33,9 @@ class AvatarSize(IntEnum): ROSTER = 32 CHAT = 48 NOTIFICATION = 48 - PROFILE = 64 TOOLTIP = 125 VCARD = 200 + PUBLISH = 200
class ArchiveState(IntEnum): NEVER = 0
===================================== gajim/filechoosers.py ===================================== --- a/gajim/filechoosers.py +++ b/gajim/filechoosers.py @@ -31,6 +31,14 @@ from gajim.common import app Filter = namedtuple('Filter', 'name pattern default')
+def _require_native(): + if app.is_flatpak(): + return True + if sys.platform in ('win32', 'darwin'): + return True + return False + + # Notes: Adding mime types to Gtk.FileFilter forces non-native dialogs
class BaseFileChooser: @@ -86,7 +94,7 @@ class BaseAvatarChooserDialog: _title = _('Choose Avatar…') _preivew_size = (100, 100)
- if app.is_flatpak(): + if _require_native(): _filters = [Filter(_('PNG files'), '*.png', True), Filter(_('JPEG files'), '*.jp*g', False), Filter(_('SVG files'), '*.svg', False)] @@ -211,11 +219,3 @@ def AvatarChooserDialog(*args, **kwargs): return NativeAvatarChooserDialog(*args, **kwargs) else: return GtkAvatarChooserDialog(*args, **kwargs) - - -def _require_native(): - if app.is_flatpak(): - return True - if sys.platform in ('win32', 'darwin'): - return True - return False
===================================== gajim/groupchat_control.py ===================================== --- a/gajim/groupchat_control.py +++ b/gajim/groupchat_control.py @@ -768,9 +768,7 @@ class GroupchatControl(ChatControlBase):
def _on_upload_avatar(self, action, param): def _on_accept(filename): - with open(filename, 'rb') as file: - data = file.read() - sha = app.interface.save_avatar(data, publish=True) + sha = app.interface.save_avatar(filename, publish=True) if sha is None: dialogs.ErrorDialog( _('Could not load image'),
===================================== gajim/gtkgui_helpers.py ===================================== --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -440,11 +440,22 @@ def scale_with_ratio(size, width, height): return size, size if height > width: ratio = height / float(width) - return int(size / ratio), size + return int(size / ratio), size else: ratio = width / float(height) return size, int(size / ratio)
+def scale_pixbuf(pixbuf, size): + width, height = scale_with_ratio(size, + pixbuf.get_width(), + pixbuf.get_height()) + return pixbuf.scale_simple(width, height, + GdkPixbuf.InterpType.BILINEAR) + +def scale_pixbuf_from_data(data, size): + pixbuf = get_pixbuf_from_data(data) + return scale_pixbuf(pixbuf, size) + def on_avatar_save_as_menuitem_activate(widget, avatar, default_name=''): from gajim import dialogs def on_continue(response, file_path):
===================================== gajim/gui_interface.py ===================================== --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -2400,16 +2400,36 @@ class Interface: UpdateGCAvatarEvent(None, contact=contact))
def save_avatar(self, data, publish=False): + """ + Save an avatar to the harddisk + + :param data: publish=False data must be bytes + publish=True data must be a path to a file + + :param publish: If publish is True, the method scales the file + to AvatarSize.PUBLISH size before saving + + returns SHA1 value of the avatar or None on error + """ if data is None: return
if publish: + with open(data, 'rb') as file: + data = file.read() pixbuf = gtkgui_helpers.get_pixbuf_from_data(data) if pixbuf is None: return - pixbuf = pixbuf.scale_simple(AvatarSize.PROFILE, - AvatarSize.PROFILE, - GdkPixbuf.InterpType.BILINEAR) + + width = pixbuf.get_width() + height = pixbuf.get_height() + if width > AvatarSize.PUBLISH or height > AvatarSize.PUBLISH: + # Scale only down, never up + width, height = gtkgui_helpers.scale_with_ratio( + AvatarSize.PUBLISH, width, height) + pixbuf = pixbuf.scale_simple(width, + height, + GdkPixbuf.InterpType.BILINEAR) publish_path = os.path.join( configpaths.get('AVATAR'), 'temp_publish') pixbuf.savev(publish_path, 'png', [], [])
===================================== gajim/profile_window.py ===================================== --- a/gajim/profile_window.py +++ b/gajim/profile_window.py @@ -124,9 +124,7 @@ class ProfileWindow:
def on_set_avatar_button_clicked(self, widget): def on_ok(path_to_file): - with open(path_to_file, 'rb') as file: - data = file.read() - sha = app.interface.save_avatar(data, publish=True) + sha = app.interface.save_avatar(path_to_file, publish=True) if sha is None: dialogs.ErrorDialog( _('Could not load image'), transient_for=self.window) @@ -156,8 +154,9 @@ class ProfileWindow: """ If right-clicked, show popup """ - pixbuf = self.xml.get_object('PHOTO_button').get_image().get_pixbuf() - if event.button == 3 and pixbuf: # right click + + if event.button == 3: + # right click menu = Gtk.Menu()
nick = app.config.get_per('accounts', self.account, 'name') @@ -167,10 +166,6 @@ class ProfileWindow: gtkgui_helpers.on_avatar_save_as_menuitem_activate, sha, nick) menu.append(menuitem) - # show clear - menuitem = Gtk.MenuItem.new_with_mnemonic(_('_Clear')) - menuitem.connect('activate', self.on_clear_button_clicked) - menu.append(menuitem) menu.connect('selection-done', lambda w:w.destroy()) # show the menu menu.show_all() @@ -224,13 +219,16 @@ class ProfileWindow: self.avatar_sha = hashlib.sha1(photo_decoded).hexdigest() if 'TYPE' in vcard_[i]: self.avatar_mime_type = vcard_[i]['TYPE'] - pixbuf = gtkgui_helpers.get_pixbuf_from_data(photo_decoded) - if pixbuf is None: - continue - pixbuf = pixbuf.scale_simple( - AvatarSize.PROFILE, AvatarSize.PROFILE, - GdkPixbuf.InterpType.BILINEAR) - image.set_from_pixbuf(pixbuf) + + scale = self.window.get_scale_factor() + surface = app.interface.get_avatar( + self.avatar_sha, AvatarSize.VCARD, scale) + if surface is None: + pixbuf = gtkgui_helpers.scale_pixbuf_from_data( + photo_decoded, AvatarSize.VCARD) + surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, + scale) + image.set_from_surface(surface) button.show() remove_avatar.show() text_button.hide()
===================================== gajim/remote_control.py ===================================== --- a/gajim/remote_control.py +++ b/gajim/remote_control.py @@ -825,9 +825,7 @@ class SignalObject(dbus.service.Object): else: invalid_file = True if not invalid_file and filesize < 16384: - with open(picture, 'rb') as fd: - data = fd.read() - sha = app.interface.save_avatar(data, publish=True) + sha = app.interface.save_avatar(picture, publish=True) if sha is None: return app.config.set_per('accounts', self.name, 'avatar_sha', sha)
===================================== gajim/vcard.py ===================================== --- a/gajim/vcard.py +++ b/gajim/vcard.py @@ -218,16 +218,17 @@ class VcardWindow: except binascii.Error as error: app.log('avatar').warning('Invalid avatar for %s: %s', jid, error) continue + pixbuf = gtkgui_helpers.get_pixbuf_from_data(photo_decoded) if pixbuf is None: continue - pixbuf = pixbuf.scale_simple( - AvatarSize.PROFILE, AvatarSize.PROFILE, - GdkPixbuf.InterpType.BILINEAR) + self.avatar = pixbuf + pixbuf = gtkgui_helpers.scale_pixbuf(pixbuf, AvatarSize.VCARD) + surface = Gdk.cairo_surface_create_from_pixbuf( + pixbuf, self.window.get_scale_factor()) image = self.xml.get_object('PHOTO_image') - image.set_from_pixbuf(pixbuf) + image.set_from_surface(surface) image.show() - self.avatar = pixbuf self.xml.get_object('user_avatar_label').show() continue if i in ('ADR', 'TEL', 'EMAIL'):
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/cc874227a137a7d7b6d7a9b8205aba4ca1...
--- View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/cc874227a137a7d7b6d7a9b8205aba4ca1... You're receiving this email because of your account on dev.gajim.org.