Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: 79b6cb15 by wurstsalat at 2022-01-13T20:19:02+01:00 AudioWidget: Typing
- - - - - c14cc32b by wurstsalat at 2022-01-13T20:38:15+01:00 ResourceSelector: Typing
- - - - - c9537bbd by wurstsalat at 2022-01-13T20:38:20+01:00 SearchView: Typing
- - - - - 23b9a50a by wurstsalat at 2022-01-13T20:38:20+01:00 Features: Typing
- - - - - a44ae974 by wurstsalat at 2022-01-13T20:46:58+01:00 SendFileDialog: Typing
- - - - -
6 changed files:
- gajim/common/storage/archive.py - gajim/gtk/features.py - gajim/gtk/file_transfer_send.py - gajim/gtk/preview_audio.py - gajim/gtk/resource_selector.py - gajim/gtk/search_view.py
Changes:
===================================== gajim/common/storage/archive.py ===================================== @@ -121,6 +121,8 @@ class LastConversationRow(NamedTuple):
class SearchLogRow(NamedTuple): + account_id: int + jid_id: int contact_name: str time: float kind: int @@ -675,8 +677,8 @@ def search_log(self, users_query_string = 'AND UPPER(contact_name) IN (?)'
sql = ''' - SELECT contact_name, time, kind, show, message, subject, - additional_data, log_line_id + SELECT account_id, jid_id, contact_name, time, kind, show, message, + subject, additional_data, log_line_id FROM logs NATURAL JOIN jids WHERE jid IN ({jids}) AND message LIKE like(?) AND kind NOT IN ({kinds})
===================================== gajim/gtk/features.py ===================================== @@ -20,7 +20,7 @@ # along with Gajim. If not, see http://www.gnu.org/licenses/.
from typing import NamedTuple -from typing import List +from typing import Optional
import os import sys @@ -38,7 +38,7 @@ class Feature(NamedTuple): tooltip: str dependency_u: str dependency_w: str - enabled: bool + enabled: Optional[bool]
class Features(Gtk.ApplicationWindow): @@ -77,7 +77,7 @@ def __init__(self) -> None:
def _on_key_press(self, _widget: Gtk.Widget, - event: Gdk.EventButton) -> None: + event: Gdk.EventKey) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy()
@@ -85,7 +85,7 @@ def _add_feature(self, feature: Feature) -> None: item = FeatureItem(feature) self.feature_listbox.add(item)
- def _get_features(self) -> List[Feature]: + def _get_features(self) -> list[Feature]: notification_sounds_available: bool = ( app.is_installed('GSOUND') or sys.platform in ('win32', 'darwin')) notification_sounds_enabled: bool = app.settings.get('sounds_on') @@ -210,7 +210,7 @@ def __init__(self, feature: Feature) -> None: self.add(self._icon) self.add(self._box)
- def _set_feature(self, available: bool, enabled: bool) -> None: + def _set_feature(self, available: bool, enabled: Optional[bool]) -> None: self._icon.get_style_context().remove_class('error-color') self._icon.get_style_context().remove_class('warning-color') self._icon.get_style_context().remove_class('success-color') @@ -219,7 +219,9 @@ def _set_feature(self, available: bool, enabled: bool) -> None: self._icon.set_from_icon_name( 'window-close-symbolic', Gtk.IconSize.MENU) self._icon.get_style_context().add_class('error-color') - elif enabled is False: + return + + if enabled is not None and not enabled: self._icon.set_from_icon_name( 'dialog-warning-symbolic', Gtk.IconSize.MENU) self._box.pack_start(self._label_disabled, True, True, 0)
===================================== gajim/gtk/file_transfer_send.py ===================================== @@ -17,16 +17,23 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see http://www.gnu.org/licenses/.
+from __future__ import annotations + +from typing import Callable +from typing import cast + from pathlib import Path
from gi.repository import Gdk from gi.repository import Gtk from gi.repository import Pango
-from nbxmpp import Namespace +from nbxmpp.namespaces import Namespace +from nbxmpp.protocol import JID
from gajim.common import app from gajim.common.i18n import _ +from gajim.common.modules.contacts import BareContact
from .filechoosers import FileChooserDialog from .resource_selector import ResourceSelector @@ -34,7 +41,11 @@
class SendFileDialog(Gtk.ApplicationWindow): - def __init__(self, contact, send_callback, transient_for): + def __init__(self, + contact: BareContact, + send_callback: Callable[..., bool], + transient_for: Gtk.Window + ) -> None: Gtk.ApplicationWindow.__init__(self) self.set_application(app.app) self.set_show_menubar(False) @@ -61,24 +72,28 @@ def __init__(self, contact, send_callback, transient_for): constraints=[Namespace.JINGLE_FILE_TRANSFER_5]) self._resource_selector.connect( 'selection-changed', self._on_resource_selection) - self._ui.resource_box.pack_start(self._resource_selector, 1, 0, 0) + self._ui.resource_box.pack_start( + self._resource_selector, True, False, 0)
- self.connect('key-press-event', self._key_press_event) + self.connect('key-press-event', self._on_key_press) self._ui.connect_signals(self) self.show_all()
- def _on_files_changed(self, _listbox, _row): + def _on_files_changed(self, _listbox: Gtk.ListBox, _row: FileRow) -> None: sensitive = bool(len(self._ui.listbox.get_children()) > 0) self._ui.files_send.set_sensitive(sensitive)
- def _on_resource_selection(self, _selector, state): + def _on_resource_selection(self, + _selector: ResourceSelector, + state: bool + ) -> None: self._ui.resource_send.set_sensitive(state)
- def _on_send_to_resource(self, _button): + def _on_send_to_resource(self, _button: Gtk.Button) -> None: resource_jid = self._resource_selector.get_jid() self._send_files(resource_jid)
- def _on_send_clicked(self, _button): + def _on_send_clicked(self, _button: Gtk.Button) -> None: count = len(self._contact.get_resources()) if count == 0 or count > 1: self._ui.send_stack.set_visible_child_name('resource_selection') @@ -87,48 +102,50 @@ def _on_send_clicked(self, _button): resource_jid = self._contact.get_resources()[0].jid self._send_files(resource_jid)
- def _send_files(self, resource_jid): - for file in self._ui.listbox.get_children(): + def _send_files(self, resource_jid: JID) -> None: + files = cast(list[FileRow], self._ui.listbox.get_children()) + for file in files: self._send_callback( - resource_jid, str(file.path), self._get_description()) + resource_jid, str(file.file_path), self._get_description()) self.destroy()
- def _select_files(self, _button): + def _select_files(self, _button: Gtk.Button) -> None: FileChooserDialog(self._set_files, select_multiple=True, transient_for=self, path=app.settings.get('last_send_dir'))
- def _remove_files(self, _button): + def _remove_files(self, _button: Gtk.Button) -> None: selected = self._ui.listbox.get_selected_rows() for item in selected: self._ui.listbox.remove(item)
- def _set_files(self, file_names): + def _set_files(self, file_names: str) -> None: + last_dir = '' for file in file_names: row = FileRow(file) - if row.path.is_dir(): + if row.file_path.is_dir(): continue - last_dir = row.path.parent + last_dir = row.file_path.parent self._ui.listbox.add(row) self._ui.listbox.show_all() app.settings.set('last_send_dir', str(last_dir))
- def _get_description(self): + def _get_description(self) -> str: buffer_ = self._ui.description.get_buffer() start, end = buffer_.get_bounds() return buffer_.get_text(start, end, False)
- def _key_press_event(self, _widget, event): + def _on_key_press(self, _widget: Gtk.Widget, event: Gdk.EventKey) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy()
class FileRow(Gtk.ListBoxRow): - def __init__(self, path): + def __init__(self, path: str) -> None: Gtk.ListBoxRow.__init__(self) - self.path = Path(path) - label = Gtk.Label(label=self.path.name) + self.file_path: Path = Path(path) + label = Gtk.Label(label=self.file_path.name) label.set_ellipsize(Pango.EllipsizeMode.END) label.set_xalign(0) self.add(label)
===================================== gajim/gtk/preview_audio.py ===================================== @@ -79,6 +79,7 @@ def _build_audio_widget(self) -> None: self.show_all()
def _setup_audio_player(self, file_path: Path) -> None: + assert self._playbin is not None self._playbin.set_property('uri', f'file://{file_path}') state_return = self._playbin.set_state(Gst.State.PAUSED) if state_return == Gst.StateChangeReturn.FAILURE: @@ -93,13 +94,17 @@ def _setup_audio_player(self, file_path: Path) -> None: bus.connect('message', self._on_bus_message)
def _on_bus_message(self, _bus: Gst.Bus, message: Gst.Message) -> None: + assert self._playbin is not None if message.type == Gst.MessageType.EOS: self._set_pause(True) self._playbin.seek_simple( Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0) elif message.type == Gst.MessageType.STATE_CHANGED: - _success, duration = self._playbin.query_duration( + success, duration = self._playbin.query_duration( Gst.Format.TIME) + if not success: + return + assert duration is not None if duration > 0: self._seek_bar.set_range(0.0, duration)
@@ -114,6 +119,7 @@ def _on_seek(self, _scroll: Gtk.ScrollType, value: float ) -> bool: + assert self._playbin is not None self._playbin.seek_simple( Gst.Format.TIME, Gst.SeekFlags.FLUSH, int(value)) return False @@ -122,13 +128,16 @@ def _on_play_clicked(self, _button: Gtk.Button) -> None: self._set_pause(not self._get_paused())
def _on_destroy(self, _widget: Gtk.Widget) -> None: + assert self._playbin is not None self._playbin.set_state(Gst.State.NULL)
def _get_paused(self) -> bool: + assert self._playbin is not None _, state, _ = self._playbin.get_state(20) return state == Gst.State.PAUSED
def _set_pause(self, paused: bool) -> None: + assert self._playbin is not None if paused: self._playbin.set_state(Gst.State.PAUSED) self._play_icon.set_from_icon_name( @@ -145,6 +154,7 @@ def _update_seek_bar(self) -> bool: self._has_timeout = False return False
+ assert self._playbin is not None if self._playbin.query(self._query): _fmt, cur_pos = self._query.parse_position() if cur_pos is not None: @@ -167,4 +177,6 @@ def _format_audio_timestamp(_widget: Gtk.Scale, ns: float) -> str:
@staticmethod def _on_realize(event_box: Gtk.EventBox) -> None: - event_box.get_window().set_cursor(get_cursor('pointer')) + window = event_box.get_window() + if window is not None: + window.set_cursor(get_cursor('pointer'))
===================================== gajim/gtk/resource_selector.py ===================================== @@ -14,7 +14,7 @@
from __future__ import annotations from typing import Optional -from typing import Tuple +from typing import cast
import locale import logging @@ -23,7 +23,6 @@ from gi.repository import Gtk
from nbxmpp import JID -from nbxmpp.namespaces import _Namespaces from nbxmpp.structs import DiscoInfo
from gajim.common import app @@ -46,7 +45,7 @@ class ResourceSelector(Gtk.ScrolledWindow):
def __init__(self, contact: BareContact, - constraints: Optional[list[_Namespaces]] = None) -> None: + constraints: Optional[list[str]] = None) -> None: Gtk.ScrolledWindow.__init__(self) self.set_shadow_type(Gtk.ShadowType.IN) self.set_size_request(-1, 200) @@ -61,7 +60,7 @@ def __init__(self, self._contact.connect('presence-update', self._on_update) self._contact.connect('caps-update', self._on_update)
- # Constraints include Namespaces a resource has to support + # Constraints include nbxmpp Namespaces a resource has to support self._constraints = constraints or []
self._set_placeholder() @@ -106,13 +105,14 @@ def _on_update(self, self._add_entries()
def get_jid(self) -> JID: - return self._listbox.get_selected_row().jid + resource_row = cast(ResourceRow, self._listbox.get_selected_row()) + return resource_row.jid
class ResourceRow(Gtk.ListBoxRow): def __init__(self, resource_contact: ResourceContact, - constraints: list[_Namespaces] + constraints: list[str] ) -> None: Gtk.ListBoxRow.__init__(self)
@@ -145,7 +145,7 @@ def __init__(self, box.add(name_label)
for constraint in constraints: - if not resource_contact.supports(str(constraint)): + if not resource_contact.supports(constraint): self.set_sensitive(False) self.set_tooltip_text(_('This devices is not compatible.'))
@@ -154,7 +154,7 @@ def __init__(self,
@staticmethod def _get_client_identity(disco_info: DiscoInfo - ) -> Tuple[Optional[str], Optional[str]]: + ) -> tuple[Optional[str], Optional[str]]: for identity in disco_info.identities: if identity.category == 'client': return identity.name, identity.type
===================================== gajim/gtk/search_view.py ===================================== @@ -35,6 +35,7 @@ from gajim.common.const import KindConstant from gajim.common.const import FILE_CATEGORIES from gajim.common.i18n import _ +from gajim.common.storage.archive import SearchLogRow
from .conversation.message_widget import MessageWidget from .builder import get_builder @@ -56,8 +57,8 @@ def __init__(self) -> None:
self._account: Optional[str] = None self._jid: Optional[JID] = None - self._results: list[str] = [] - self._scope: Optional[str] = None + self._results: list[SearchLogRow] = [] + self._scope: str = 'everywhere'
self._ui = get_builder('search_view.ui') self._ui.results_listbox.set_header_func(self._header_func) @@ -86,6 +87,9 @@ def _header_func(row: Union[CounterRow, ResultRow], else: row.set_header(RowHeader(row.account, row.jid, row.time)) else: + if isinstance(row, CounterRow): + row.set_header(None) + return date1 = time.strftime('%x', time.localtime(row.time)) date2 = time.strftime('%x', time.localtime(before.time)) if before.jid != row.jid: @@ -184,13 +188,13 @@ def _on_search(self, entry: Gtk.Entry) -> None:
def _filter_results_for_files(self, filetypes: list[str]) -> None: if 'file' in filetypes: - results = [] + results: list[SearchLogRow] = [] for result in self._results: if result.additional_data.get_value('gajim', 'oob_url'): results.append(result) self._results = results else: - results = [] + results: list[SearchLogRow] = [] for result in self._results: url = result.additional_data.get_value('gajim', 'oob_url') if url is None: @@ -223,11 +227,14 @@ def _add_results(self) -> None: accounts = self._get_accounts() for msg in self._results[:25]: if self._scope == 'everywhere': + archive_jid = app.storage.archive.get_jid_from_id(msg.jid_id) result_row = ResultRow( msg, - accounts.get(msg.account_id), - app.storage.archive.get_jid_from_id(msg.jid_id).jid) + accounts[msg.account_id], + archive_jid.jid) else: + assert self._account is not None + assert self._jid is not None result_row = ResultRow(msg, self._account, self._jid)
self._ui.results_listbox.add(result_row) @@ -242,8 +249,8 @@ def _on_edge_reached(self, self._add_results()
@staticmethod - def _get_accounts() -> dict[str, str]: - accounts: dict[str, str] = {} + def _get_accounts() -> dict[int, str]: + accounts: dict[int, str] = {} for account in app.settings.get_accounts(): account_id = app.storage.archive.get_account_id(account) accounts[account_id] = account
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/aa3b45d6b434923303e9442263b06319...