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

Commits:

7 changed files:

Changes:

  • gajim/gtk/conversation/quote_widget.py
    ... ... @@ -14,9 +14,12 @@
    14 14
     
    
    15 15
     from __future__ import annotations
    
    16 16
     
    
    17
    +import typing
    
    18
    +
    
    17 19
     from gi.repository import Gtk
    
    18 20
     
    
    19
    -from .. import types
    
    21
    +if typing.TYPE_CHECKING:
    
    22
    +    from .message_widget import MessageWidget
    
    20 23
     
    
    21 24
     
    
    22 25
     class QuoteWidget(Gtk.Box):
    
    ... ... @@ -34,8 +37,7 @@ def __init__(self, account: str) -> None:
    34 37
     
    
    35 38
             self._message_widget = None
    
    36 39
     
    
    37
    -    def attach_message_widget(self,
    
    38
    -                              message_widget: types.MessageWidget) -> None:
    
    40
    +    def attach_message_widget(self, message_widget: MessageWidget) -> None:
    
    39 41
     
    
    40 42
             # Purpose of this method is to prevent circular imports
    
    41 43
             if self._message_widget is not None:
    

  • gajim/gtk/conversation/rows/base.py
    ... ... @@ -15,7 +15,6 @@
    15 15
     from __future__ import annotations
    
    16 16
     
    
    17 17
     from typing import Optional
    
    18
    -from typing import Union
    
    19 18
     
    
    20 19
     from datetime import datetime
    
    21 20
     
    
    ... ... @@ -24,18 +23,7 @@
    24 23
     from gi.repository import Pango
    
    25 24
     
    
    26 25
     from gajim.common import app
    
    27
    -from gajim.common.i18n import _
    
    28 26
     from gajim.common.helpers import from_one_line
    
    29
    -from gajim.common.helpers import is_retraction_allowed
    
    30
    -
    
    31
    -from gajim.common.modules.contacts import BareContact
    
    32
    -from gajim.common.modules.contacts import GroupchatContact
    
    33
    -from gajim.common.modules.contacts import GroupchatParticipant
    
    34
    -
    
    35
    -from ...util import wrap_with_event_box
    
    36
    -from ...types import MessageRowType
    
    37
    -
    
    38
    -ContactT = Union[BareContact, GroupchatContact, GroupchatParticipant]
    
    39 27
     
    
    40 28
     
    
    41 29
     class BaseRow(Gtk.ListBoxRow):
    
    ... ... @@ -102,84 +90,3 @@ def create_name_widget(name: str, is_self: bool) -> Gtk.Label:
    102 90
         @staticmethod
    
    103 91
         def __destroy(widget: Gtk.Widget) -> None:
    
    104 92
             app.check_finalize(widget)
    105
    -
    
    106
    -
    
    107
    -@wrap_with_event_box
    
    108
    -class MoreMenuButton(Gtk.Button):
    
    109
    -    def __init__(self,
    
    110
    -                 row: MessageRowType,
    
    111
    -                 contact: ContactT,
    
    112
    -                 name: str
    
    113
    -                 ) -> None:
    
    114
    -
    
    115
    -        Gtk.Button.__init__(self)
    
    116
    -        self.set_valign(Gtk.Align.START)
    
    117
    -        self.set_halign(Gtk.Align.END)
    
    118
    -        self.set_relief(Gtk.ReliefStyle.NONE)
    
    119
    -
    
    120
    -        self.get_style_context().add_class('conversation-more-button')
    
    121
    -
    
    122
    -        self._row = row
    
    123
    -        self._contact = contact
    
    124
    -        self._name = name
    
    125
    -
    
    126
    -        image = Gtk.Image.new_from_icon_name(
    
    127
    -            'feather-more-horizontal-symbolic', Gtk.IconSize.BUTTON)
    
    128
    -        self.add(image)
    
    129
    -        self.connect('clicked', self._on_click)
    
    130
    -
    
    131
    -    def _on_click(self, _button: Gtk.Button) -> None:
    
    132
    -        show_retract = False
    
    133
    -        if isinstance(self._contact, GroupchatContact):
    
    134
    -            disco_info = app.storage.cache.get_last_disco_info(
    
    135
    -                self._contact.jid)
    
    136
    -            contact = self._contact.get_resource(self._name)
    
    137
    -            self_contact = self._contact.get_self()
    
    138
    -            assert self_contact is not None
    
    139
    -            is_allowed = is_retraction_allowed(self_contact, contact)
    
    140
    -            if disco_info.has_message_moderation and is_allowed:
    
    141
    -                show_retract = True
    
    142
    -        self._create_popover(show_retract)
    
    143
    -
    
    144
    -    def _create_popover(self, show_retract: bool) -> None:
    
    145
    -        menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
    
    146
    -        menu_box.get_style_context().add_class('padding-6')
    
    147
    -
    
    148
    -        quote_button = Gtk.ModelButton()
    
    149
    -        quote_button.set_halign(Gtk.Align.START)
    
    150
    -        quote_button.connect('clicked', self._row.on_quote_message)
    
    151
    -        quote_button.set_label(_('Quote…'))
    
    152
    -        quote_button.set_image(Gtk.Image.new_from_icon_name(
    
    153
    -            'mail-reply-sender-symbolic', Gtk.IconSize.MENU))
    
    154
    -        menu_box.add(quote_button)
    
    155
    -
    
    156
    -        copy_button = Gtk.ModelButton()
    
    157
    -        copy_button.set_halign(Gtk.Align.START)
    
    158
    -        copy_button.connect('clicked', self._row.on_copy_message)
    
    159
    -        copy_button.set_label(_('Copy'))
    
    160
    -        copy_button.set_image(Gtk.Image.new_from_icon_name(
    
    161
    -            'edit-copy-symbolic', Gtk.IconSize.MENU))
    
    162
    -        menu_box.add(copy_button)
    
    163
    -
    
    164
    -        if show_retract:
    
    165
    -            retract_button = Gtk.ModelButton()
    
    166
    -            retract_button.set_halign(Gtk.Align.START)
    
    167
    -            retract_button.connect(
    
    168
    -                'clicked', self._row.on_retract_message)
    
    169
    -            retract_button.set_label(_('Retract'))
    
    170
    -            retract_button.set_image(Gtk.Image.new_from_icon_name(
    
    171
    -                'edit-undo-symbolic', Gtk.IconSize.MENU))
    
    172
    -            menu_box.add(retract_button)
    
    173
    -
    
    174
    -        menu_box.show_all()
    
    175
    -
    
    176
    -        popover = Gtk.PopoverMenu()
    
    177
    -        popover.add(menu_box)
    
    178
    -        popover.set_relative_to(self)
    
    179
    -        popover.set_position(Gtk.PositionType.BOTTOM)
    
    180
    -        popover.connect('closed', self._on_closed)
    
    181
    -        popover.popup()
    
    182
    -
    
    183
    -    @staticmethod
    
    184
    -    def _on_closed(popover: Gtk.Popover) -> None:
    
    185
    -        GLib.idle_add(popover.destroy)

  • gajim/gtk/conversation/rows/message.py
    ... ... @@ -44,16 +44,15 @@
    44 44
     from gajim.common.i18n import Q_
    
    45 45
     
    
    46 46
     from .base import BaseRow
    
    47
    -from .base import MoreMenuButton
    
    47
    +from .widgets import MoreMenuButton
    
    48 48
     from ..message_widget import MessageWidget
    
    49 49
     from ...dialogs import InputDialog
    
    50 50
     from ...dialogs import DialogButton
    
    51 51
     from ...preview import PreviewWidget
    
    52
    -from ...types import ConversationRowType
    
    53
    -from ...types import MessageRowType
    
    54 52
     from ...util import format_fingerprint
    
    55 53
     from ...util import get_cursor
    
    56 54
     
    
    55
    +
    
    57 56
     MERGE_TIMEFRAME = timedelta(seconds=120)
    
    58 57
     
    
    59 58
     
    
    ... ... @@ -255,10 +254,10 @@ def _on_avatar_clicked(self,
    255 254
         def _on_realize(event_box: Gtk.EventBox) -> None:
    
    256 255
             event_box.get_window().set_cursor(get_cursor('pointer'))
    
    257 256
     
    
    258
    -    def is_same_sender(self, message: MessageRowType) -> bool:
    
    257
    +    def is_same_sender(self, message: MessageRow) -> bool:
    
    259 258
             return message.name == self.name
    
    260 259
     
    
    261
    -    def is_same_encryption(self, message: MessageRowType) -> bool:
    
    260
    +    def is_same_encryption(self, message: MessageRow) -> bool:
    
    262 261
             message_details = self._get_encryption_details(message.additional_data)
    
    263 262
             own_details = self._get_encryption_details(self.additional_data)
    
    264 263
             if message_details is None and own_details is None:
    
    ... ... @@ -271,7 +270,7 @@ def is_same_encryption(self, message: MessageRowType) -> bool:
    271 270
                     return True
    
    272 271
             return False
    
    273 272
     
    
    274
    -    def is_mergeable(self, message: ConversationRowType) -> bool:
    
    273
    +    def is_mergeable(self, message: BaseRow) -> bool:
    
    275 274
             if message.type != self.type:
    
    276 275
                 return False
    
    277 276
             if not self.is_same_sender(message):
    

  • gajim/gtk/conversation/rows/widgets.py
    ... ... @@ -12,8 +12,29 @@
    12 12
     # You should have received a copy of the GNU General Public License
    
    13 13
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14 14
     
    
    15
    +from __future__ import annotations
    
    16
    +
    
    17
    +import typing
    
    18
    +from typing import Union
    
    19
    +
    
    15 20
     from gi.repository import Gtk
    
    16 21
     from gi.repository import Pango
    
    22
    +from gi.repository import GLib
    
    23
    +
    
    24
    +from gajim.common import app
    
    25
    +from gajim.common.i18n import _
    
    26
    +from gajim.common.helpers import is_retraction_allowed
    
    27
    +from gajim.common.modules.contacts import BareContact
    
    28
    +from gajim.common.modules.contacts import GroupchatContact
    
    29
    +from gajim.common.modules.contacts import GroupchatParticipant
    
    30
    +
    
    31
    +from ...util import wrap_with_event_box
    
    32
    +
    
    33
    +if typing.TYPE_CHECKING:
    
    34
    +    from .message import MessageRow
    
    35
    +
    
    36
    +
    
    37
    +ContactT = Union[BareContact, GroupchatContact, GroupchatParticipant]
    
    17 38
     
    
    18 39
     
    
    19 40
     class SimpleLabel(Gtk.Label):
    
    ... ... @@ -23,3 +44,87 @@ def __init__(self) -> None:
    23 44
             self.set_line_wrap(True)
    
    24 45
             self.set_xalign(0)
    
    25 46
             self.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
    
    47
    +
    
    48
    +
    
    49
    +@wrap_with_event_box
    
    50
    +class MoreMenuButton(Gtk.Button):
    
    51
    +    def __init__(self,
    
    52
    +                 row: MessageRow,
    
    53
    +                 contact: ContactT,
    
    54
    +                 name: str
    
    55
    +                 ) -> None:
    
    56
    +
    
    57
    +        Gtk.Button.__init__(self)
    
    58
    +        self.set_valign(Gtk.Align.START)
    
    59
    +        self.set_halign(Gtk.Align.END)
    
    60
    +        self.set_relief(Gtk.ReliefStyle.NONE)
    
    61
    +
    
    62
    +        self.get_style_context().add_class('conversation-more-button')
    
    63
    +
    
    64
    +        self._row = row
    
    65
    +        self._contact = contact
    
    66
    +        self._name = name
    
    67
    +
    
    68
    +        image = Gtk.Image.new_from_icon_name(
    
    69
    +            'feather-more-horizontal-symbolic', Gtk.IconSize.BUTTON)
    
    70
    +        self.add(image)
    
    71
    +        self.connect('clicked', self._on_click)
    
    72
    +
    
    73
    +    def _on_click(self, _button: Gtk.Button) -> None:
    
    74
    +        show_retract = False
    
    75
    +        if isinstance(self._contact, GroupchatContact):
    
    76
    +            disco_info = app.storage.cache.get_last_disco_info(
    
    77
    +                self._contact.jid)
    
    78
    +            assert disco_info is not None
    
    79
    +
    
    80
    +            contact = self._contact.get_resource(self._name)
    
    81
    +            self_contact = self._contact.get_self()
    
    82
    +            assert self_contact is not None
    
    83
    +
    
    84
    +            is_allowed = is_retraction_allowed(self_contact, contact)
    
    85
    +            if disco_info.has_message_moderation and is_allowed:
    
    86
    +                show_retract = True
    
    87
    +        self._create_popover(show_retract)
    
    88
    +
    
    89
    +    def _create_popover(self, show_retract: bool) -> None:
    
    90
    +        menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
    
    91
    +        menu_box.get_style_context().add_class('padding-6')
    
    92
    +
    
    93
    +        quote_button = Gtk.ModelButton()
    
    94
    +        quote_button.set_halign(Gtk.Align.START)
    
    95
    +        quote_button.connect('clicked', self._row.on_quote_message)
    
    96
    +        quote_button.set_label(_('Quote…'))
    
    97
    +        quote_button.set_image(Gtk.Image.new_from_icon_name(
    
    98
    +            'mail-reply-sender-symbolic', Gtk.IconSize.MENU))
    
    99
    +        menu_box.add(quote_button)
    
    100
    +
    
    101
    +        copy_button = Gtk.ModelButton()
    
    102
    +        copy_button.set_halign(Gtk.Align.START)
    
    103
    +        copy_button.connect('clicked', self._row.on_copy_message)
    
    104
    +        copy_button.set_label(_('Copy'))
    
    105
    +        copy_button.set_image(Gtk.Image.new_from_icon_name(
    
    106
    +            'edit-copy-symbolic', Gtk.IconSize.MENU))
    
    107
    +        menu_box.add(copy_button)
    
    108
    +
    
    109
    +        if show_retract:
    
    110
    +            retract_button = Gtk.ModelButton()
    
    111
    +            retract_button.set_halign(Gtk.Align.START)
    
    112
    +            retract_button.connect(
    
    113
    +                'clicked', self._row.on_retract_message)
    
    114
    +            retract_button.set_label(_('Retract'))
    
    115
    +            retract_button.set_image(Gtk.Image.new_from_icon_name(
    
    116
    +                'edit-undo-symbolic', Gtk.IconSize.MENU))
    
    117
    +            menu_box.add(retract_button)
    
    118
    +
    
    119
    +        menu_box.show_all()
    
    120
    +
    
    121
    +        popover = Gtk.PopoverMenu()
    
    122
    +        popover.add(menu_box)
    
    123
    +        popover.set_relative_to(self)
    
    124
    +        popover.set_position(Gtk.PositionType.BOTTOM)
    
    125
    +        popover.connect('closed', self._on_closed)
    
    126
    +        popover.popup()
    
    127
    +
    
    128
    +    @staticmethod
    
    129
    +    def _on_closed(popover: Gtk.Popover) -> None:
    
    130
    +        GLib.idle_add(popover.destroy)

  • gajim/gtk/conversation/view.py
    ... ... @@ -12,6 +12,8 @@
    12 12
     # You should have received a copy of the GNU General Public License
    
    13 13
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14 14
     
    
    15
    +from __future__ import annotations
    
    16
    +
    
    15 17
     from typing import Dict
    
    16 18
     from typing import Set
    
    17 19
     from typing import Optional
    
    ... ... @@ -38,6 +40,7 @@
    38 40
     from gajim.common.modules.contacts import GroupchatParticipant
    
    39 41
     from gajim.common.modules.httpupload import HTTPFileTransfer
    
    40 42
     
    
    43
    +from .rows.base import BaseRow
    
    41 44
     from .rows.read_marker import ReadMarkerRow
    
    42 45
     from .rows.scroll_hint import ScrollHintRow
    
    43 46
     from .rows.message import MessageRow
    
    ... ... @@ -51,7 +54,6 @@
    51 54
     from .rows.muc_join_left import MUCJoinLeft
    
    52 55
     from .rows.muc_user_status import MUCUserStatus
    
    53 56
     
    
    54
    -from ..types import ConversationRowType
    
    55 57
     from ..util import scroll_to_end
    
    56 58
     
    
    57 59
     log = logging.getLogger('gajim.gui.conversation_view')
    
    ... ... @@ -300,7 +302,7 @@ def _add_date_row(self, timestamp: datetime) -> None:
    300 302
     
    
    301 303
             row.set_merged(False)
    
    302 304
     
    
    303
    -    def _check_for_merge(self, message: ConversationRowType) -> None:
    
    305
    +    def _check_for_merge(self, message: BaseRow) -> None:
    
    304 306
             if message.type != 'chat':
    
    305 307
                 return
    
    306 308
     
    
    ... ... @@ -434,7 +436,7 @@ def get_row_by_stanza_id(self, stanza_id: str) -> Optional[MessageRow]:
    434 436
                     return row
    
    435 437
             return None
    
    436 438
     
    
    437
    -    def iter_rows(self) -> Generator[ConversationRowType, None, None]:
    
    439
    +    def iter_rows(self) -> Generator[BaseRow, None, None]:
    
    438 440
             for row in self.get_children():
    
    439 441
                 yield row
    
    440 442
     
    

  • gajim/gtk/types.py
    ... ... @@ -36,22 +36,6 @@
    36 36
         from .conversation.rows.scroll_hint import ScrollHintRow
    
    37 37
     
    
    38 38
     
    
    39
    -ConversationRowType = Union[
    
    40
    -    'CallRow',
    
    41
    -    'CommandOutputRow',
    
    42
    -    'DateRow',
    
    43
    -    'FileTransferJingleRow',
    
    44
    -    'FileTransferRow',
    
    45
    -    'InfoMessage',
    
    46
    -    'MessageRow',
    
    47
    -    'MUCJoinLeft',
    
    48
    -    'MUCSubject',
    
    49
    -    'MUCUserStatus',
    
    50
    -    'ReadMarkerRow',
    
    51
    -    'ScrollHintRow'
    
    52
    -]
    
    53
    -
    
    54
    -MessageRowType = Union['MessageRow']
    
    55 39
     
    
    56 40
     ControlType = Union [
    
    57 41
         'ChatControl',
    

  • pyrightconfig.json
    ... ... @@ -24,6 +24,7 @@
    24 24
             "gajim/gtk/conversation/jump_to_end_button.py",
    
    25 25
             "gajim/gtk/conversation/plain_widget.py",
    
    26 26
             "gajim/gtk/conversation/quote_widget.py",
    
    27
    +        "gajim/gtk/conversation/rows/base.py",
    
    27 28
             "gajim/gtk/conversation/rows/command_output.py",
    
    28 29
             "gajim/gtk/conversation/rows/date.py",
    
    29 30
             "gajim/gtk/conversation/rows/file_transfer.py",