Philipp Hörist pushed to branch master at gajim / gajim

Commits:

2 changed files:

Changes:

  • gajim/gtk/conversation/rows/message.py
    ... ... @@ -44,22 +44,21 @@
    44 44
     from gajim.common.helpers import to_user_string
    
    45 45
     from gajim.common.i18n import _
    
    46 46
     from gajim.common.i18n import is_rtl_text
    
    47
    -from gajim.common.i18n import Q_
    
    48 47
     from gajim.common.modules.contacts import GroupchatContact
    
    49 48
     from gajim.common.types import ChatContactT
    
    50 49
     
    
    51 50
     from .base import BaseRow
    
    51
    +from .widgets import AvatarBox
    
    52 52
     from .widgets import DateTimeLabel
    
    53 53
     from .widgets import NicknameLabel
    
    54
    +from .widgets import MessageIcons
    
    54 55
     from .widgets import MoreMenuButton
    
    55 56
     from ..message_widget import MessageWidget
    
    56 57
     from ...dialogs import InputDialog
    
    57 58
     from ...dialogs import DialogButton
    
    58
    -from ...menus import get_groupchat_participant_menu
    
    59 59
     from ...preview import PreviewWidget
    
    60
    -from ...util import GajimPopover
    
    61 60
     from ...util import format_fingerprint
    
    62
    -from ...util import get_cursor
    
    61
    +
    
    63 62
     
    
    64 63
     MERGE_TIMEFRAME = timedelta(seconds=120)
    
    65 64
     
    
    ... ... @@ -179,19 +178,9 @@ def __init__(self,
    179 178
                     self.set_receipt()
    
    180 179
     
    
    181 180
             self._meta_box.pack_start(self._message_icons, False, True, 0)
    
    182
    -        avatar = self._get_avatar(kind, name)
    
    183
    -        self._avatar_image = Gtk.Image.new_from_surface(avatar)
    
    184 181
     
    
    185
    -        if self._is_groupchat:
    
    186
    -            avatar_placeholder = Gtk.EventBox()
    
    187
    -            avatar_placeholder.connect(
    
    188
    -                'button-press-event', self._on_avatar_clicked, name)
    
    189
    -            avatar_placeholder.connect('realize', self._on_realize)
    
    190
    -        else:
    
    191
    -            avatar_placeholder = Gtk.Box()
    
    192
    -        avatar_placeholder.set_size_request(AvatarSize.ROSTER, -1)
    
    193
    -        avatar_placeholder.set_valign(Gtk.Align.START)
    
    194
    -        avatar_placeholder.add(self._avatar_image)
    
    182
    +        avatar = self._get_avatar(kind, name)
    
    183
    +        self._avatar_box = AvatarBox(self._contact, name, avatar)
    
    195 184
     
    
    196 185
             self._bottom_box = Gtk.Box(spacing=6)
    
    197 186
             self._bottom_box.add(self._message_widget)
    
    ... ... @@ -201,11 +190,9 @@ def __init__(self,
    201 190
                 self._message_widget.set_direction(Gtk.TextDirection.RTL)
    
    202 191
     
    
    203 192
             more_menu_button = MoreMenuButton(self, self._contact, name)
    
    204
    -        more_menu_button.set_hexpand(True)
    
    205
    -        more_menu_button.set_halign(Gtk.Align.END)
    
    206 193
             self._bottom_box.pack_end(more_menu_button, False, True, 0)
    
    207 194
     
    
    208
    -        self.grid.attach(avatar_placeholder, 0, 0, 1, 2)
    
    195
    +        self.grid.attach(self._avatar_box, 0, 0, 1, 2)
    
    209 196
             self.grid.attach(self._meta_box, 1, 0, 1, 1)
    
    210 197
             self.grid.attach(self._bottom_box, 1, 1, 1, 1)
    
    211 198
     
    
    ... ... @@ -268,45 +255,6 @@ def _get_avatar(self, kind: str, name: str) -> Optional[cairo.ImageSurface]:
    268 255
             assert not isinstance(avatar, GdkPixbuf.Pixbuf)
    
    269 256
             return avatar
    
    270 257
     
    
    271
    -    def _on_avatar_clicked(self,
    
    272
    -                           _widget: Gtk.Widget,
    
    273
    -                           event: Gdk.EventButton,
    
    274
    -                           name: str
    
    275
    -                           ) -> int:
    
    276
    -        if event.type == Gdk.EventType.BUTTON_PRESS:
    
    277
    -            if event.button == 1:
    
    278
    -                app.window.activate_action('mention', GLib.Variant('s', name))
    
    279
    -            elif event.button == 3:
    
    280
    -                self._show_participant_menu(name, event)
    
    281
    -
    
    282
    -        return Gdk.EVENT_STOP
    
    283
    -
    
    284
    -    def _show_participant_menu(self, nick: str, event: Gdk.EventButton) -> None:
    
    285
    -        assert isinstance(self._contact, GroupchatContact)
    
    286
    -        if not self._contact.is_joined:
    
    287
    -            return
    
    288
    -
    
    289
    -        self_contact = self._contact.get_self()
    
    290
    -        assert self_contact is not None
    
    291
    -
    
    292
    -        if nick == self_contact.name:
    
    293
    -            # Don’t show menu for us
    
    294
    -            return
    
    295
    -
    
    296
    -        contact = self._contact.get_resource(nick)
    
    297
    -        menu = get_groupchat_participant_menu(self._contact.account,
    
    298
    -                                              self_contact,
    
    299
    -                                              contact)
    
    300
    -
    
    301
    -        popover = GajimPopover(menu, relative_to=self, event=event)
    
    302
    -        popover.popup()
    
    303
    -
    
    304
    -    @staticmethod
    
    305
    -    def _on_realize(event_box: Gtk.EventBox) -> None:
    
    306
    -        window = event_box.get_window()
    
    307
    -        if window is not None:
    
    308
    -            window.set_cursor(get_cursor('pointer'))
    
    309
    -
    
    310 258
         def is_same_sender(self, message: MessageRow) -> bool:
    
    311 259
             return message.name == self.name
    
    312 260
     
    
    ... ... @@ -487,63 +435,17 @@ def set_error(self, tooltip: str) -> None:
    487 435
     
    
    488 436
         def update_avatar(self) -> None:
    
    489 437
             avatar = self._get_avatar(self.kind, self.name)
    
    490
    -        self._avatar_image.set_from_surface(avatar)
    
    438
    +        self._avatar_box.set_from_surface(avatar)
    
    491 439
     
    
    492 440
         def set_merged(self, merged: bool) -> None:
    
    493 441
             self._merged = merged
    
    494 442
             if merged:
    
    495 443
                 self.get_style_context().add_class('merged')
    
    496
    -            self._avatar_image.set_no_show_all(True)
    
    497
    -            self._avatar_image.hide()
    
    498 444
                 self._meta_box.set_no_show_all(True)
    
    499 445
                 self._meta_box.hide()
    
    500 446
             else:
    
    501 447
                 self.get_style_context().remove_class('merged')
    
    502
    -            self._avatar_image.set_no_show_all(False)
    
    503
    -            self._avatar_image.show()
    
    504 448
                 self._meta_box.set_no_show_all(False)
    
    505 449
                 self._meta_box.show()
    
    506 450
     
    
    507
    -
    
    508
    -class MessageIcons(Gtk.Box):
    
    509
    -    def __init__(self) -> None:
    
    510
    -        Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
    
    511
    -
    
    512
    -        self._correction_image = Gtk.Image.new_from_icon_name(
    
    513
    -            'document-edit-symbolic', Gtk.IconSize.MENU)
    
    514
    -        self._correction_image.set_no_show_all(True)
    
    515
    -        self._correction_image.get_style_context().add_class('dim-label')
    
    516
    -
    
    517
    -        self._marker_image = Gtk.Image()
    
    518
    -        self._marker_image.set_no_show_all(True)
    
    519
    -        self._marker_image.get_style_context().add_class('dim-label')
    
    520
    -
    
    521
    -        self._error_image = Gtk.Image.new_from_icon_name(
    
    522
    -            'dialog-warning-symbolic', Gtk.IconSize.MENU)
    
    523
    -        self._error_image.get_style_context().add_class('warning-color')
    
    524
    -        self._error_image.set_no_show_all(True)
    
    525
    -
    
    526
    -        self.add(self._correction_image)
    
    527
    -        self.add(self._marker_image)
    
    528
    -        self.add(self._error_image)
    
    529
    -        self.show_all()
    
    530
    -
    
    531
    -    def set_receipt_icon_visible(self, visible: bool) -> None:
    
    532
    -        if not app.settings.get('positive_184_ack'):
    
    533
    -            return
    
    534
    -        self._marker_image.set_visible(visible)
    
    535
    -        self._marker_image.set_from_icon_name(
    
    536
    -            'feather-check-symbolic', Gtk.IconSize.MENU)
    
    537
    -        self._marker_image.set_tooltip_text(Q_('?Message state:Received'))
    
    538
    -
    
    539
    -    def set_correction_icon_visible(self, visible: bool) -> None:
    
    540
    -        self._correction_image.set_visible(visible)
    
    541
    -
    
    542
    -    def set_correction_tooltip(self, text: str) -> None:
    
    543
    -        self._correction_image.set_tooltip_markup(text)
    
    544
    -
    
    545
    -    def set_error_icon_visible(self, visible: bool) -> None:
    
    546
    -        self._error_image.set_visible(visible)
    
    547
    -
    
    548
    -    def set_error_tooltip(self, text: str) -> None:
    
    549
    -        self._error_image.set_tooltip_markup(text)
    451
    +        self._avatar_box.set_merged(merged)

  • gajim/gtk/conversation/rows/widgets.py
    ... ... @@ -15,14 +15,18 @@
    15 15
     from __future__ import annotations
    
    16 16
     
    
    17 17
     from typing import TYPE_CHECKING
    
    18
    +from typing import Optional
    
    18 19
     
    
    19 20
     from datetime import datetime
    
    20 21
     
    
    21 22
     from gi.repository import Gtk
    
    23
    +from gi.repository import Gdk
    
    22 24
     from gi.repository import Pango
    
    23 25
     from gi.repository import GLib
    
    26
    +import cairo
    
    24 27
     
    
    25 28
     from gajim.common import app
    
    29
    +from gajim.common.const import AvatarSize
    
    26 30
     from gajim.common.i18n import Q_
    
    27 31
     from gajim.common.helpers import is_retraction_allowed
    
    28 32
     from gajim.common.modules.contacts import GroupchatContact
    
    ... ... @@ -31,7 +35,10 @@
    31 35
     if TYPE_CHECKING:
    
    32 36
         from .message import MessageRow
    
    33 37
     
    
    38
    +from ...menus import get_groupchat_participant_menu
    
    34 39
     from ...util import wrap_with_event_box
    
    40
    +from ...util import get_cursor
    
    41
    +from ...util import GajimPopover
    
    35 42
     
    
    36 43
     
    
    37 44
     class SimpleLabel(Gtk.Label):
    
    ... ... @@ -55,6 +62,7 @@ def __init__(self,
    55 62
             self.set_valign(Gtk.Align.START)
    
    56 63
             self.set_halign(Gtk.Align.END)
    
    57 64
             self.set_relief(Gtk.ReliefStyle.NONE)
    
    65
    +        self.set_hexpand(True)
    
    58 66
     
    
    59 67
             self.get_style_context().add_class('conversation-more-button')
    
    60 68
     
    
    ... ... @@ -196,3 +204,118 @@ def __init__(self, name: str, from_us: bool) -> None:
    196 204
                 css_class = 'gajim-incoming-nickname'
    
    197 205
     
    
    198 206
             self.get_style_context().add_class(css_class)
    
    207
    +
    
    208
    +
    
    209
    +class MessageIcons(Gtk.Box):
    
    210
    +    def __init__(self) -> None:
    
    211
    +        Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
    
    212
    +
    
    213
    +        self._correction_image = Gtk.Image.new_from_icon_name(
    
    214
    +            'document-edit-symbolic', Gtk.IconSize.MENU)
    
    215
    +        self._correction_image.set_no_show_all(True)
    
    216
    +        self._correction_image.get_style_context().add_class('dim-label')
    
    217
    +
    
    218
    +        self._marker_image = Gtk.Image()
    
    219
    +        self._marker_image.set_no_show_all(True)
    
    220
    +        self._marker_image.get_style_context().add_class('dim-label')
    
    221
    +
    
    222
    +        self._error_image = Gtk.Image.new_from_icon_name(
    
    223
    +            'dialog-warning-symbolic', Gtk.IconSize.MENU)
    
    224
    +        self._error_image.get_style_context().add_class('warning-color')
    
    225
    +        self._error_image.set_no_show_all(True)
    
    226
    +
    
    227
    +        self.add(self._correction_image)
    
    228
    +        self.add(self._marker_image)
    
    229
    +        self.add(self._error_image)
    
    230
    +        self.show_all()
    
    231
    +
    
    232
    +    def set_receipt_icon_visible(self, visible: bool) -> None:
    
    233
    +        if not app.settings.get('positive_184_ack'):
    
    234
    +            return
    
    235
    +        self._marker_image.set_visible(visible)
    
    236
    +        self._marker_image.set_from_icon_name(
    
    237
    +            'feather-check-symbolic', Gtk.IconSize.MENU)
    
    238
    +        self._marker_image.set_tooltip_text(Q_('?Message state:Received'))
    
    239
    +
    
    240
    +    def set_correction_icon_visible(self, visible: bool) -> None:
    
    241
    +        self._correction_image.set_visible(visible)
    
    242
    +
    
    243
    +    def set_correction_tooltip(self, text: str) -> None:
    
    244
    +        self._correction_image.set_tooltip_markup(text)
    
    245
    +
    
    246
    +    def set_error_icon_visible(self, visible: bool) -> None:
    
    247
    +        self._error_image.set_visible(visible)
    
    248
    +
    
    249
    +    def set_error_tooltip(self, text: str) -> None:
    
    250
    +        self._error_image.set_tooltip_markup(text)
    
    251
    +
    
    252
    +
    
    253
    +class AvatarBox(Gtk.EventBox):
    
    254
    +    def __init__(self,
    
    255
    +                 contact: ChatContactT,
    
    256
    +                 name: str,
    
    257
    +                 avatar: Optional[cairo.ImageSurface],
    
    258
    +                 ) -> None:
    
    259
    +
    
    260
    +        Gtk.EventBox.__init__(self)
    
    261
    +
    
    262
    +        self.set_size_request(AvatarSize.ROSTER, -1)
    
    263
    +        self.set_valign(Gtk.Align.START)
    
    264
    +
    
    265
    +        self._contact = contact
    
    266
    +
    
    267
    +        self._image = Gtk.Image.new_from_surface(avatar)
    
    268
    +        self.add(self._image)
    
    269
    +
    
    270
    +        if self._contact.is_groupchat:
    
    271
    +            self.connect('realize', self._on_realize)
    
    272
    +
    
    273
    +        self.connect('button-press-event',
    
    274
    +                     self._on_avatar_clicked, name)
    
    275
    +
    
    276
    +    def set_from_surface(self, surface: Optional[cairo.ImageSurface]) -> None:
    
    277
    +        self._image.set_from_surface(surface)
    
    278
    +
    
    279
    +    def set_merged(self, merged: bool) -> None:
    
    280
    +        self._image.set_no_show_all(merged)
    
    281
    +        self._image.set_visible(not merged)
    
    282
    +
    
    283
    +    @staticmethod
    
    284
    +    def _on_realize(event_box: Gtk.EventBox) -> None:
    
    285
    +        window = event_box.get_window()
    
    286
    +        if window is not None:
    
    287
    +            window.set_cursor(get_cursor('pointer'))
    
    288
    +
    
    289
    +    def _on_avatar_clicked(self,
    
    290
    +                           _widget: Gtk.Widget,
    
    291
    +                           event: Gdk.EventButton,
    
    292
    +                           name: str
    
    293
    +                           ) -> int:
    
    294
    +
    
    295
    +        if event.type == Gdk.EventType.BUTTON_PRESS:
    
    296
    +            if event.button == 1:
    
    297
    +                app.window.activate_action('mention', GLib.Variant('s', name))
    
    298
    +            elif event.button == 3:
    
    299
    +                self._show_participant_menu(name, event)
    
    300
    +
    
    301
    +        return Gdk.EVENT_STOP
    
    302
    +
    
    303
    +    def _show_participant_menu(self, nick: str, event: Gdk.EventButton) -> None:
    
    304
    +        assert isinstance(self._contact, GroupchatContact)
    
    305
    +        if not self._contact.is_joined:
    
    306
    +            return
    
    307
    +
    
    308
    +        self_contact = self._contact.get_self()
    
    309
    +        assert self_contact is not None
    
    310
    +
    
    311
    +        if nick == self_contact.name:
    
    312
    +            # Don’t show menu for us
    
    313
    +            return
    
    314
    +
    
    315
    +        contact = self._contact.get_resource(nick)
    
    316
    +        menu = get_groupchat_participant_menu(self._contact.account,
    
    317
    +                                              self_contact,
    
    318
    +                                              contact)
    
    319
    +
    
    320
    +        popover = GajimPopover(menu, relative_to=self, event=event)
    
    321
    +        popover.popup()