Daniel Brötzmann pushed to branch master at gajim / gajim

Commits:

3 changed files:

Changes:

  • gajim/gtk/call_widget.py
    ... ... @@ -12,21 +12,27 @@
    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 typing import Optional  # pylint: disable=unused-import
    
    15
    +from __future__ import annotations
    
    16
    +from typing import Any
    
    17
    +from typing import List
    
    18
    +from typing import Optional
    
    16 19
     
    
    17 20
     import logging
    
    18 21
     import time
    
    19 22
     
    
    20 23
     from gi.repository import GObject
    
    24
    +from gi.repository import Gdk
    
    21 25
     from gi.repository import Gtk
    
    22 26
     
    
    23 27
     from nbxmpp.namespaces import Namespace
    
    24 28
     
    
    25 29
     from gajim.common import app
    
    30
    +from gajim.common import types
    
    26 31
     from gajim.common.const import JingleState
    
    27 32
     from gajim.common.const import KindConstant
    
    28 33
     from gajim.common.helpers import AdditionalDataDict
    
    29 34
     from gajim.common.i18n import _
    
    35
    +from gajim.common.jingle_rtp import JingleAudio
    
    30 36
     from gajim.common.nec import NetworkEvent
    
    31 37
     
    
    32 38
     from .gstreamer import create_gtk_widget
    
    ... ... @@ -50,7 +56,7 @@ class CallWidget(Gtk.Box):
    50 56
             ),
    
    51 57
         }
    
    52 58
     
    
    53
    -    def __init__(self, account, contact):
    
    59
    +    def __init__(self, account: str, contact: types.BareContact) -> None:
    
    54 60
             Gtk.Box.__init__(self)
    
    55 61
             self.set_no_show_all(True)
    
    56 62
     
    
    ... ... @@ -62,7 +68,7 @@ def __init__(self, account, contact):
    62 68
             # having to show a new call row
    
    63 69
             self._incoming_video_event = None
    
    64 70
     
    
    65
    -        self._jingle = {
    
    71
    +        self._jingle: dict(str, JingleObject) = {
    
    66 72
                 'audio': JingleObject(
    
    67 73
                     JingleState.NULL,
    
    68 74
                     self._update_audio),
    
    ... ... @@ -77,20 +83,22 @@ def __init__(self, account, contact):
    77 83
             self.add(self._ui.av_box)
    
    78 84
             self.connect('destroy', self._on_destroy)
    
    79 85
     
    
    80
    -        dtmf = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#']
    
    86
    +        dtmf: list(str) = [
    
    87
    +            '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#']
    
    81 88
             for key in dtmf:
    
    82 89
                 button = self._ui.get_object(key + '_button')
    
    83
    -            button.connect('pressed', self._on_num_button_pressed, key)
    
    84
    -            button.connect('released', self._on_num_button_released)
    
    90
    +            button.connect(
    
    91
    +                'button-press-event', self._on_num_button_press, key)
    
    92
    +            button.connect('button-release-event', self._on_num_button_release)
    
    85 93
     
    
    86 94
             self._ui.connect_signals(self)
    
    87 95
     
    
    88
    -    def _on_destroy(self, *args):
    
    96
    +    def _on_destroy(self, *args: Any) -> None:
    
    89 97
             for jingle_type in ('audio', 'video'):
    
    90 98
                 self._close_jingle_content(jingle_type, shutdown=True)
    
    91 99
             self._jingle.clear()
    
    92 100
     
    
    93
    -    def detect_av(self):
    
    101
    +    def detect_av(self) -> None:
    
    94 102
             if (self._contact.supports(Namespace.JINGLE_ICE_UDP) and
    
    95 103
                     app.is_installed('FARSTREAM')):
    
    96 104
                 self._jingle['audio'].available = self._contact.supports(
    
    ... ... @@ -104,23 +112,23 @@ def detect_av(self):
    104 112
                 self._jingle['audio'].available = False
    
    105 113
                 self._jingle['video'].available = False
    
    106 114
     
    
    107
    -    def get_jingle_available(self, content_type):
    
    115
    +    def get_jingle_available(self, content_type: str) -> bool:
    
    108 116
             return self._jingle[content_type].available
    
    109 117
     
    
    110
    -    def _on_call_with_mic(self, _button):
    
    118
    +    def _on_call_with_mic(self, _button: Gtk.Button) -> None:
    
    111 119
             self._on_jingle_button_toggled(['audio'])
    
    112 120
             self._ui.av_start_box.hide()
    
    113 121
     
    
    114
    -    def _on_call_with_mic_and_cam(self, _button):
    
    122
    +    def _on_call_with_mic_and_cam(self, _button: Gtk.Button) -> None:
    
    115 123
             self._on_jingle_button_toggled(['audio', 'video'])
    
    116 124
             self._ui.av_start_box.hide()
    
    117 125
     
    
    118
    -    def _on_answer_video_clicked(self, button):
    
    126
    +    def _on_answer_video_clicked(self, button: Gtk.Button) -> None:
    
    119 127
             self.accept_call(self._incoming_video_event)
    
    120 128
             self._incoming_video_event = None
    
    121 129
             button.hide()
    
    122 130
     
    
    123
    -    def _on_end_call_clicked(self, _widget):
    
    131
    +    def _on_end_call_clicked(self, _button: Gtk.Button) -> None:
    
    124 132
             self._close_jingle_content('audio')
    
    125 133
             self._close_jingle_content('video')
    
    126 134
             self._ui.jingle_audio_state.set_no_show_all(True)
    
    ... ... @@ -129,10 +137,10 @@ def _on_end_call_clicked(self, _widget):
    129 137
             self.hide()
    
    130 138
             self.emit('call-ended')
    
    131 139
     
    
    132
    -    def _on_video(self, *args):
    
    140
    +    def _on_video(self, _button: Gtk.Button) -> None:
    
    133 141
             self._on_jingle_button_toggled(['video'])
    
    134 142
     
    
    135
    -    def _on_jingle_button_toggled(self, jingle_types):
    
    143
    +    def _on_jingle_button_toggled(self, jingle_types: List[str]) -> None:
    
    136 144
             if all(item in jingle_types for item in ['audio', 'video']):
    
    137 145
                 # Both 'audio' and 'video' in jingle_types
    
    138 146
                 sid = self._client.get_module('Jingle').start_audio_video(
    
    ... ... @@ -160,7 +168,7 @@ def _on_jingle_button_toggled(self, jingle_types):
    160 168
                     self._set_jingle_state('video', JingleState.CONNECTING, sid)
    
    161 169
                     self._store_outgoing_call(sid)
    
    162 170
     
    
    163
    -    def _store_outgoing_call(self, sid):
    
    171
    +    def _store_outgoing_call(self, sid: str) -> None:
    
    164 172
             additional_data = AdditionalDataDict()
    
    165 173
             additional_data.set_value('gajim', 'sid', sid)
    
    166 174
             app.storage.archive.insert_into_logs(
    
    ... ... @@ -170,17 +178,30 @@ def _store_outgoing_call(self, sid):
    170 178
                 KindConstant.CALL_OUTGOING,
    
    171 179
                 additional_data=additional_data)
    
    172 180
     
    
    173
    -    def _on_num_button_pressed(self, _widget, num):
    
    181
    +    def _on_num_button_press(self,
    
    182
    +                             _button: Gtk.Button,
    
    183
    +                             _event: Gdk.EventButton,
    
    184
    +                             num: int
    
    185
    +                             ) -> None:
    
    174 186
             self._get_audio_content().start_dtmf(num)
    
    175 187
     
    
    176
    -    def _on_num_button_released(self, _released):
    
    188
    +    def _on_num_button_release(self,
    
    189
    +                               _button: Gtk.Button,
    
    190
    +                               _event: Gdk.EventButton
    
    191
    +                               ) -> None:
    
    177 192
             self._get_audio_content().stop_dtmf()
    
    178 193
     
    
    179
    -    def _on_mic_volume_changed(self, _widget, value):
    
    194
    +    def _on_mic_volume_changed(self,
    
    195
    +                               _button: Gtk.VolumeButton,
    
    196
    +                               value: float
    
    197
    +                               ) -> None:
    
    180 198
             self._get_audio_content().set_mic_volume(value / 100)
    
    181 199
             app.settings.set('audio_input_volume', int(value))
    
    182 200
     
    
    183
    -    def _on_output_volume_changed(self, _widget, value):
    
    201
    +    def _on_output_volume_changed(self,
    
    202
    +                                  _button: Gtk.VolumeButton,
    
    203
    +                                  value: float
    
    204
    +                                  ) -> None:
    
    184 205
             self._get_audio_content().set_out_volume(value / 100)
    
    185 206
             app.settings.set('audio_output_volume', int(value))
    
    186 207
     
    
    ... ... @@ -195,7 +216,7 @@ def process_event(self, event):
    195 216
                 self._on_jingle_error(event)
    
    196 217
     
    
    197 218
         def _on_jingle_request(self, event):
    
    198
    -        content_types = []
    
    219
    +        content_types: list(str) = []
    
    199 220
             for item in event.contents:
    
    200 221
                 content_types.append(item.media)
    
    201 222
             if not any(item in ('audio', 'video') for item in content_types):
    
    ... ... @@ -273,7 +294,7 @@ def _on_jingle_error(self, event):
    273 294
                     JingleState.ERROR,
    
    274 295
                     reason=event.reason)
    
    275 296
     
    
    276
    -    def start_call(self):
    
    297
    +    def start_call(self) -> None:
    
    277 298
             audio_state = self._jingle['audio'].state
    
    278 299
             video_state = self._jingle['video'].state
    
    279 300
             if audio_state == JingleState.NULL and video_state == JingleState.NULL:
    
    ... ... @@ -307,7 +328,8 @@ def accept_call(self, session):
    307 328
             if video is not None:
    
    308 329
                 session.approve_content('video')
    
    309 330
     
    
    310
    -    def decline_call(self, session):
    
    331
    +    @staticmethod
    
    332
    +    def decline_call(session):
    
    311 333
             if not session:
    
    312 334
                 return
    
    313 335
     
    
    ... ... @@ -322,7 +344,7 @@ def decline_call(self, session):
    322 344
                 if video is not None:
    
    323 345
                     session.reject_content('video')
    
    324 346
     
    
    325
    -    def _update_audio(self):
    
    347
    +    def _update_audio(self) -> None:
    
    326 348
             audio_state = self._jingle['audio'].state
    
    327 349
             video_state = self._jingle['video'].state
    
    328 350
             if self._jingle['video'].available:
    
    ... ... @@ -381,7 +403,7 @@ def _update_audio(self):
    381 403
             if not self._jingle['audio'].sid:
    
    382 404
                 self._ui.audio_buttons_box.set_sensitive(False)
    
    383 405
     
    
    384
    -    def _update_video(self):
    
    406
    +    def _update_video(self) -> None:
    
    385 407
             audio_state = self._jingle['audio'].state
    
    386 408
             video_state = self._jingle['video'].state
    
    387 409
     
    
    ... ... @@ -494,7 +516,10 @@ def _set_jingle_state(self, jingle_type: str, state: str, sid: str = None,
    494 516
             jingle.sid = new_sid
    
    495 517
             jingle.update()
    
    496 518
     
    
    497
    -    def _stop_jingle(self, sid=None, reason=None):
    
    519
    +    def _stop_jingle(self,
    
    520
    +                     sid: Optional[str] = None,
    
    521
    +                     reason: Optional[str] = None
    
    522
    +                     ) -> None:
    
    498 523
             audio_sid = self._jingle['audio'].sid
    
    499 524
             video_sid = self._jingle['video'].sid
    
    500 525
             if audio_sid and sid in (audio_sid, None):
    
    ... ... @@ -502,8 +527,10 @@ def _stop_jingle(self, sid=None, reason=None):
    502 527
             if video_sid and sid in (video_sid, None):
    
    503 528
                 self._close_jingle_content('video')
    
    504 529
     
    
    505
    -    def _close_jingle_content(self, jingle_type: str,
    
    506
    -                              shutdown: Optional[bool] = False) -> None:
    
    530
    +    def _close_jingle_content(self,
    
    531
    +                              jingle_type: str,
    
    532
    +                              shutdown: Optional[bool] = False
    
    533
    +                              ) -> None:
    
    507 534
             jingle = self._jingle[jingle_type]
    
    508 535
             if not jingle.sid:
    
    509 536
                 return
    
    ... ... @@ -520,7 +547,7 @@ def _close_jingle_content(self, jingle_type: str,
    520 547
                 jingle.state = JingleState.NULL
    
    521 548
                 jingle.update()
    
    522 549
     
    
    523
    -    def _get_audio_content(self):
    
    550
    +    def _get_audio_content(self) -> Optional[JingleAudio]:
    
    524 551
             session = self._client.get_module('Jingle').get_jingle_session(
    
    525 552
                 self._contact.jid, self._jingle['audio'].sid)
    
    526 553
             return session.get_content('audio')
    

  • gajim/gtk/gstreamer.py
    ... ... @@ -12,13 +12,19 @@
    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 typing import Optional
    
    16
    +from typing import Tuple
    
    17
    +
    
    18
    +from gi.repository import Gtk
    
    15 19
     try:
    
    16 20
         from gi.repository import Gst
    
    17 21
     except Exception:
    
    18 22
         pass
    
    19 23
     
    
    20 24
     
    
    21
    -def create_gtk_widget():
    
    25
    +def create_gtk_widget() -> Tuple[Optional[Gst.Element],
    
    26
    +                                 Optional[Gtk.Widget],
    
    27
    +                                 Optional[str]]:
    
    22 28
         gtkglsink = Gst.ElementFactory.make('gtkglsink', None)
    
    23 29
         if gtkglsink is not None:
    
    24 30
             glsinkbin = Gst.ElementFactory.make('glsinkbin', None)
    

  • gajim/gtk/util.py
    ... ... @@ -28,6 +28,7 @@
    28 28
     from importlib import import_module
    
    29 29
     from functools import wraps
    
    30 30
     from functools import lru_cache
    
    31
    +from pathlib import Path
    
    31 32
     
    
    32 33
     try:
    
    33 34
         from PIL import Image
    
    ... ... @@ -39,7 +40,9 @@
    39 40
     from gi.repository import GLib
    
    40 41
     from gi.repository import Pango
    
    41 42
     from gi.repository import GdkPixbuf
    
    43
    +import cairo
    
    42 44
     import nbxmpp
    
    45
    +from nbxmpp import JID
    
    43 46
     from nbxmpp.structs import LocationData
    
    44 47
     
    
    45 48
     from gajim.common import app
    
    ... ... @@ -155,8 +158,13 @@ def icon_exists(name: str) -> bool:
    155 158
         return _icon_theme.has_icon(name)
    
    156 159
     
    
    157 160
     
    
    158
    -def load_icon(icon_name, widget=None, size=16, pixbuf=False,
    
    159
    -              scale=None, flags=Gtk.IconLookupFlags.FORCE_SIZE):
    
    161
    +def load_icon(icon_name: str,
    
    162
    +              widget: Optional[Any] = None,
    
    163
    +              size: int = 16,
    
    164
    +              pixbuf: bool = False,
    
    165
    +              scale: Optional[int] = None,
    
    166
    +              flags: Gtk.IconLookupFlags = Gtk.IconLookupFlags.FORCE_SIZE
    
    167
    +              ) -> Optional[Union[GdkPixbuf.Pixbuf, cairo.Surface]]:
    
    160 168
     
    
    161 169
         if widget is not None:
    
    162 170
             scale = widget.get_scale_factor()
    
    ... ... @@ -170,15 +178,16 @@ def load_icon(icon_name, widget=None, size=16, pixbuf=False,
    170 178
                 icon_name, size, scale, flags)
    
    171 179
             if iconinfo is None:
    
    172 180
                 log.info('No icon found for %s', icon_name)
    
    173
    -            return
    
    181
    +            return None
    
    174 182
             if pixbuf:
    
    175 183
                 return iconinfo.load_icon()
    
    176 184
             return iconinfo.load_surface(None)
    
    177 185
         except GLib.GError as error:
    
    178 186
             log.error('Unable to load icon %s: %s', icon_name, str(error))
    
    187
    +    return None
    
    179 188
     
    
    180 189
     
    
    181
    -def get_app_icon_list(scale_widget):
    
    190
    +def get_app_icon_list(scale_widget: Any) -> List[GdkPixbuf.Pixbuf]:
    
    182 191
         pixbufs = []
    
    183 192
         for size in (16, 32, 48, 64, 128):
    
    184 193
             pixbuf = load_icon('org.gajim.Gajim', scale_widget, size, pixbuf=True)
    
    ... ... @@ -194,15 +203,15 @@ def get_icon_name(name: str,
    194 203
             name = 'notinroster'
    
    195 204
     
    
    196 205
         if iconset is not None:
    
    197
    -        return '%s-%s' % (iconset, name)
    
    206
    +        return f'{iconset}-{name}'
    
    198 207
     
    
    199 208
         if transport is not None:
    
    200
    -        return '%s-%s' % (transport, name)
    
    209
    +        return f'{transport}-{name}'
    
    201 210
     
    
    202 211
         iconset = app.settings.get('iconset')
    
    203 212
         if not iconset:
    
    204 213
             iconset = 'dcraven'
    
    205
    -    return '%s-%s' % (iconset, name)
    
    214
    +    return f'{iconset}-{name}'
    
    206 215
     
    
    207 216
     
    
    208 217
     def load_user_iconsets() -> None:
    
    ... ... @@ -517,7 +526,7 @@ def format_fingerprint(fingerprint: str) -> str:
    517 526
         return buf.rstrip().upper()
    
    518 527
     
    
    519 528
     
    
    520
    -def find_widget(name, container):
    
    529
    +def find_widget(name: str, container: Gtk.Widget) -> Optional[Gtk.Widget]:
    
    521 530
         for child in container.get_children():
    
    522 531
             if Gtk.Buildable.get_name(child) == name:
    
    523 532
                 return child
    
    ... ... @@ -527,7 +536,7 @@ def find_widget(name, container):
    527 536
     
    
    528 537
     
    
    529 538
     class MultiLineLabel(Gtk.Label):
    
    530
    -    def __init__(self, *args, **kwargs):
    
    539
    +    def __init__(self, *args: Any, **kwargs: any) -> None:
    
    531 540
             Gtk.Label.__init__(self, *args, **kwargs)
    
    532 541
             self.set_line_wrap(True)
    
    533 542
             self.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
    
    ... ... @@ -535,16 +544,16 @@ def __init__(self, *args, **kwargs):
    535 544
     
    
    536 545
     
    
    537 546
     class MaxWidthComboBoxText(Gtk.ComboBoxText):
    
    538
    -    def __init__(self, *args, **kwargs):
    
    547
    +    def __init__(self, *args: Any, **kwargs: Any) -> None:
    
    539 548
             Gtk.ComboBoxText.__init__(self, *args, **kwargs)
    
    540
    -        self._max_width = 100
    
    549
    +        self._max_width: int = 100
    
    541 550
             text_renderer = self.get_cells()[0]
    
    542 551
             text_renderer.set_property('ellipsize', Pango.EllipsizeMode.END)
    
    543 552
     
    
    544
    -    def set_max_size(self, size):
    
    553
    +    def set_max_size(self, size: int) -> None:
    
    545 554
             self._max_width = size
    
    546 555
     
    
    547
    -    def do_get_preferred_width(self):
    
    556
    +    def do_get_preferred_width(self) -> Tuple[int, int]:
    
    548 557
             minimum_width, natural_width = Gtk.ComboBoxText.do_get_preferred_width(
    
    549 558
                 self)
    
    550 559
     
    
    ... ... @@ -639,12 +648,16 @@ def scale_pixbuf(pixbuf: GdkPixbuf.Pixbuf,
    639 648
                                    GdkPixbuf.InterpType.BILINEAR)
    
    640 649
     
    
    641 650
     
    
    642
    -def scale_pixbuf_from_data(data: bytes, size: int) -> Optional[GdkPixbuf.Pixbuf]:
    
    651
    +def scale_pixbuf_from_data(data: bytes,
    
    652
    +                           size: int
    
    653
    +                           ) -> Optional[GdkPixbuf.Pixbuf]:
    
    643 654
         pixbuf = get_pixbuf_from_data(data)
    
    644 655
         return scale_pixbuf(pixbuf, size)
    
    645 656
     
    
    646 657
     
    
    647
    -def load_pixbuf(path, size=None):
    
    658
    +def load_pixbuf(path: Union[str, Path],
    
    659
    +                size: Optional[int] = None
    
    660
    +                ) -> Optional[GdkPixbuf.Pixbuf]:
    
    648 661
         try:
    
    649 662
             if size is None:
    
    650 663
                 return GdkPixbuf.Pixbuf.new_from_file(str(path))
    
    ... ... @@ -720,7 +733,10 @@ def get_app_windows(account: str) -> List[Gtk.Window]:
    720 733
         return windows
    
    721 734
     
    
    722 735
     
    
    723
    -def get_app_window(name, account=None, jid=None):
    
    736
    +def get_app_window(name: str,
    
    737
    +                   account: Optional[str] = None,
    
    738
    +                   jid: Optional[Union[str, JID]] = None
    
    739
    +                   ) -> Optional[Gtk.Window]:
    
    724 740
         for win in app.app.get_windows():
    
    725 741
             if type(win).__name__ != name:
    
    726 742
                 continue
    
    ... ... @@ -736,7 +752,7 @@ def get_app_window(name, account=None, jid=None):
    736 752
         return None
    
    737 753
     
    
    738 754
     
    
    739
    -def open_window(name, **kwargs):
    
    755
    +def open_window(name: str, **kwargs: Any) -> Gtk.Window:
    
    740 756
         window = get_app_window(name,
    
    741 757
                                 kwargs.get('account'),
    
    742 758
                                 kwargs.get('jid'))