gajim.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2026
October
September
August
July
June
May
April
March
February
January
2025
December
November
October
September
August
July
June
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
List overview
Download
Commits
December 2021
----- 2026 -----
October 2026
September 2026
August 2026
July 2026
June 2026
May 2026
April 2026
March 2026
February 2026
January 2026
----- 2025 -----
December 2025
November 2025
October 2025
September 2025
August 2025
July 2025
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
commits@gajim.org
1 participants
197 discussions
Start a n
N
ew thread
[Git][gajim/gajim][master] 6 commits: AccountWizard: Typing
by Daniel Brötzmann (@wurstsalat)
22 Dec '21
22 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: 813143be by wurstsalat at 2021-12-22T21:04:46+01:00 AccountWizard: Typing - - - - - 89450395 by wurstsalat at 2021-12-22T21:08:18+01:00 AppSideBar: Typing - - - - - 51ad2f92 by wurstsalat at 2021-12-22T21:26:30+01:00 AvatarSelector: Typing - - - - - 7c145ffa by wurstsalat at 2021-12-22T21:37:07+01:00 ChangePassword: Typing - - - - - ca9aee26 by wurstsalat at 2021-12-22T21:45:48+01:00 ChatListStack: Typing - - - - - d26bb934 by wurstsalat at 2021-12-22T21:56:04+01:00 AddContact: List connected accounts only - - - - - 6 changed files: - gajim/gtk/account_wizard.py - gajim/gtk/add_contact.py - gajim/gtk/app_side_bar.py - gajim/gtk/avatar_selector.py - gajim/gtk/change_password.py - gajim/gtk/chat_list_stack.py Changes: ===================================== gajim/gtk/account_wizard.py ===================================== @@ -12,8 +12,9 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <
http://www.gnu.org/licenses/
>. -from typing import Optional +from typing import Any from typing import List +from typing import Optional from typing import Tuple from typing import Union @@ -35,6 +36,7 @@ from nbxmpp.errors import StanzaError from nbxmpp.errors import MalformedStanzaError from nbxmpp.errors import RegisterStanzaError +from nbxmpp.task import Task from gajim.common import app from gajim.common import configpaths @@ -101,7 +103,7 @@ def __init__(self) -> None: def get_currenct_method(self) -> str: return self._method - def _on_button_clicked(self, _page, button_name): + def _on_button_clicked(self, _page: Gtk.Widget, button_name: str) -> None: if button_name == 'login': if self.get_page('login').is_advanced(): self.show_page('advanced', @@ -112,7 +114,10 @@ def _on_button_clicked(self, _page, button_name): elif button_name == 'signup': self.show_page('signup', Gtk.StackTransitionType.SLIDE_LEFT) - def _on_assistant_button_clicked(self, _assistant, button_name): + def _on_assistant_button_clicked(self, + _assistant: Assistant, + button_name: str + ) -> None: page = self.get_current_page() if button_name == 'login': @@ -185,7 +190,10 @@ def _on_assistant_button_clicked(self, _assistant, button_name): elif page == 'redirect': self.show_page('login', Gtk.StackTransitionType.SLIDE_RIGHT) - def _on_page_changed(self, _assistant, page_name): + def _on_page_changed(self, + _assistant: Assistant, + page_name: str + ) -> None: if page_name == 'signup': self._method = page_name self.get_page('signup').focus() @@ -240,13 +248,19 @@ def _disconnect(self) -> None: self._client = None @staticmethod - def _on_stanza_sent(_client, _signal_name, stanza): + def _on_stanza_sent(_client: Client, + _signal_name: str, + stanza: Any + ) -> None: app.nec.push_incoming_event(NetworkEvent('stanza-sent', account='AccountWizard', stanza=stanza)) @staticmethod - def _on_stanza_received(_client, _signal_name, stanza): + def _on_stanza_received(_client: Client, + _signal_name: str, + stanza: Any + ) -> None: app.nec.push_incoming_event(NetworkEvent('stanza-received', account='AccountWizard', stanza=stanza)) @@ -304,7 +318,7 @@ def _register_with_server(self, ignore_all_errors: bool = False) -> None: self._client.connect() - def _on_login_successful(self, client, _signal_name): + def _on_login_successful(self, client: Client, _signal_name: str) -> None: account = self._generate_account_name(client.domain) proxy_name = None if client.proxy is not None: @@ -319,11 +333,14 @@ def _on_login_successful(self, client, _signal_name): self.get_page('success').set_account(account) self.show_page('success', Gtk.StackTransitionType.SLIDE_LEFT) - def _on_connected(self, client, _signal_name): + def _on_connected(self, client: Client, _signal_name: str) -> None: client.get_module('Register').request_register_form( callback=self._on_register_form) - def _on_anonymous_supported(self, client, _signal_name): + def _on_anonymous_supported(self, + client: Client, + _signal_name: str + ) -> None: account = self._generate_account_name(client.domain) proxy_name = None if client.proxy is not None: @@ -339,7 +356,7 @@ def _on_anonymous_supported(self, client, _signal_name): self.get_page('success').set_account(account) self.show_page('success', Gtk.StackTransitionType.SLIDE_LEFT) - def _on_disconnected(self, client, _signal_name): + def _on_disconnected(self, client: Client, _signal_name: str) -> None: domain, error, text = client.get_error() if domain == StreamError.SASL: if error == 'anonymous-not-supported': @@ -380,7 +397,10 @@ def _on_disconnected(self, client, _signal_name): self._client.destroy() self._client = None - def _on_connection_failed(self, _client, _signal_name): + def _on_connection_failed(self, + _client: Client, + _signal_name: str + ) -> None: self._show_error_page(_('Connection failed'), _('Connection failed'), _('Gajim was not able to reach the server. ' @@ -407,7 +427,7 @@ def _generate_account_name(domain: str) -> str: i += 1 return domain - def _on_register_form(self, task): + def _on_register_form(self, task: Task) -> None: try: result = task.finish() except (StanzaError, MalformedStanzaError) as error: @@ -446,7 +466,7 @@ def _submit_form(self) -> None: form, callback=self._on_register_result) - def _on_register_result(self, task): + def _on_register_result(self, task: Task) -> None: try: task.finish() except RegisterStanzaError as error: @@ -505,7 +525,7 @@ def _set_error_text(self, 'without an error message') self._show_error_page(_('Error'), _('Error'), error_text) - def _on_destroy(self, *args): + def _on_destroy(self, *args: Any) -> None: self._disconnect() self._destroyed = True @@ -540,10 +560,10 @@ def __init__(self) -> None: def focus(self) -> None: self._ui.log_in_address_entry.grab_focus() - def _on_login(self, *args): + def _on_login(self, *args: Any) -> None: self.emit('clicked', 'login') - def _on_signup(self, *args): + def _on_signup(self, *args: Any) -> None: self.emit('clicked', 'signup') def _create_server_completion(self) -> None: @@ -558,11 +578,11 @@ def _create_server_completion(self) -> None: address_model.append((server,)) self._ui.log_in_address_entry.get_completion().set_model(address_model) - def _on_address_changed(self, entry): + def _on_address_changed(self, entry: Gtk.Entry) -> None: self._update_completion(entry) self._set_complete() - def _update_completion(self, entry): + def _update_completion(self, entry: Gtk.Entry) -> None: text = entry.get_text() if '@' not in text: self._show_icon(False) @@ -580,10 +600,10 @@ def _show_icon(self, show: bool) -> None: self._ui.log_in_address_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, icon) - def _on_address_entry_activate(self, _widget): + def _on_address_entry_activate(self, _entry: Gtk.Entry) -> None: GLib.idle_add(self._ui.log_in_password_entry.grab_focus) - def _on_password_entry_activate(self, _widget): + def _on_password_entry_activate(self, _entry: Gtk.Entry) -> None: if self._ui.log_in_button.get_sensitive(): self._ui.log_in_button.activate() @@ -605,7 +625,7 @@ def _validate_jid(self, address: str) -> bool: self._show_icon(False) return True - def _set_complete(self, *args): + def _set_complete(self, *args: Any) -> None: address = self._validate_jid(self._ui.log_in_address_entry.get_text()) password = self._ui.log_in_password_entry.get_text() self._ui.log_in_button.set_sensitive(address and password) @@ -620,7 +640,7 @@ def get_credentials(self) -> Tuple[str, str]: class Signup(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.complete: bool = False self.title: str = _('Create New Account') @@ -660,13 +680,13 @@ def _create_server_completion(self) -> None: self._ui.server_comboboxtext_sign_up_entry.get_completion().set_model( servers_model) - def _on_visit_server(self, _widget): + def _on_visit_server(self, _button: Gtk.Button) -> int: server = self._ui.server_comboboxtext_sign_up_entry.get_text().strip() server = f'https://{server}' open_uri(server) return Gdk.EVENT_STOP - def _set_complete(self, *args): + def _set_complete(self, *args: Any) -> None: try: self.get_server() except Exception: @@ -689,7 +709,7 @@ def get_server(self) -> str: self._ui.server_comboboxtext_sign_up_entry.get_text()) @staticmethod - def _on_activate_link(_label, uri): + def _on_activate_link(_label: Gtk.Label, uri: str) -> int: # We have to use this, because the default GTK handler # is not cross-platform compatible open_uri(uri) @@ -703,7 +723,7 @@ def get_default_button(self) -> str: class AdvancedSettings(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.title: str = _('Advanced settings') self.complete: bool = False @@ -719,7 +739,7 @@ def __init__(self): self.show_all() @staticmethod - def _on_proxy_manager(_widget): + def _on_proxy_manager(_button: Gtk.Button) -> None: app.app.activate_action('manage-proxies') def update_proxy_list(self) -> None: @@ -811,7 +831,7 @@ def _is_custom_host_set(self) -> bool: def _is_proxy_set(self) -> bool: return self._ui.proxies_combobox.get_active() != 0 - def _set_complete(self, *args): + def _set_complete(self, *args: Any) -> None: self.complete = False if self._is_proxy_set(): self.complete = True @@ -875,7 +895,7 @@ def set_warning(self, self._ui.trust_cert_checkbutton.set_visible( Gio.TlsCertificateFlags.UNKNOWN_CA in errors) - def _on_view_cert(self, _button): + def _on_view_cert(self, _button: Gtk.Button) -> None: open_window('CertificateDialog', account=self._domain, transient_for=self.get_toplevel(), @@ -896,9 +916,9 @@ class Form(Page): def __init__(self) -> None: Page.__init__(self) self.set_valign(Gtk.Align.FILL) - self.complete = False + self.complete: bool = False self.title: str = _('Create Account') - self._current_form = None + self._current_form: Optional[Any] = None heading = Gtk.Label(label=_('Create Account')) heading.get_style_context().add_class('large-header') @@ -914,11 +934,11 @@ def __init__(self) -> None: def has_form(self) -> bool: return self._current_form is not None - def _on_is_valid(self, _widget, is_valid): + def _on_is_valid(self, _widget: DataFormWidget, is_valid: bool) -> None: self.complete = is_valid self.update_page_complete() - def add_form(self, form): + def add_form(self, form: Any) -> None: self.remove_form() options = {'hide-fallback-fields': True, @@ -933,7 +953,7 @@ def get_credentials(self) -> Tuple[str, str]: return (self._current_form.get_form()['username'].value, self._current_form.get_form()['password'].value) - def get_submit_form(self): + def get_submit_form(self) -> Any: return self._current_form.get_submit_form() def remove_form(self) -> None: @@ -971,7 +991,7 @@ def set_redirect(self, link: str, instructions: str) -> None: self._ui.instructions.set_text(instructions) self._link = link - def _on_link_button(self, _button): + def _on_link_button(self, _button:Gtk.Button) -> None: open_uri(self._link) def get_visible_buttons(self) -> List[str]: @@ -985,9 +1005,9 @@ def __init__(self) -> None: self.set_heading(_('Account has been added successfully')) self._account: Optional[str] = None - self._our_jid = None - self._label = None - self._color = None + self._our_jid: Optional[str] = None + self._label: Optional[str] = None + self._color: Optional[str] = None self._ui = get_builder('account_wizard.ui') self.pack_start(self._ui.account_label_box, True, True, 0) @@ -1013,28 +1033,28 @@ def set_account(self, account: str) -> None: def account(self) -> Optional[str]: return self._account - def _add_css_provider(self): + def _add_css_provider(self) -> Gtk.CssProvider: context = self._ui.badge_preview.get_style_context() provider = Gtk.CssProvider() context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) return provider - def _on_name_changed(self, entry): + def _on_name_changed(self, entry: Gtk.Entry): self._label = entry.get_text() self._ui.badge_preview.set_text(self._label or self._our_jid) self._save_config() - def _on_color_set(self, button): + def _on_color_set(self, button: Gtk.ColorButton): rgba = button.get_rgba() self._color = rgba.to_string() self._set_badge_color(self._color) self._save_config() - def _set_badge_color(self, color): + def _set_badge_color(self, color: str) -> None: css = '.badge { background-color: %s; font-size: 100%%; }' % color self._provider.load_from_data(bytes(css.encode())) - def _save_config(self): + def _save_config(self) -> None: app.settings.set_account_setting( self._account, 'account_color', self._color) if self._label: ===================================== gajim/gtk/add_contact.py ===================================== @@ -93,6 +93,7 @@ def _on_button_clicked(self, ) -> None: page = self.get_current_page() account, _ = self.get_page('address').get_account_and_jid() + assert account is not None if button_name == 'next': self._start_disco() @@ -132,6 +133,7 @@ def _start_disco(self) -> None: self.show_page('progress', Gtk.StackTransitionType.SLIDE_LEFT) account, jid = self.get_page('address').get_account_and_jid() + assert account is not None self._disco_info(account, jid) @as_task @@ -213,7 +215,7 @@ def __init__(self, account: Optional[str], jid: Optional[JID]) -> None: self._ui.account_combo.connect('changed', self._on_account_changed) self._ui.address_entry.connect('changed', self._set_complete) - accounts = app.get_enabled_accounts_with_labels() + accounts = app.get_enabled_accounts_with_labels(connected_only=True) liststore = self._ui.account_combo.get_model() for acc in accounts: liststore.append(acc) ===================================== gajim/gtk/app_side_bar.py ===================================== @@ -17,11 +17,12 @@ from gajim.common import app -from gajim.gui.util import load_icon +from .app_page import AppPage +from .util import load_icon class AppSideBar(Gtk.ListBox): - def __init__(self, app_page): + def __init__(self, app_page: AppPage) -> None: Gtk.ListBox.__init__(self) self.set_valign(Gtk.Align.START) self.set_selection_mode(Gtk.SelectionMode.SINGLE) @@ -40,15 +41,17 @@ def __init__(self, app_page): GLib.idle_add(self.unselect_all) @staticmethod - def _on_app_row_activated(_listbox, _row): + def _on_app_row_activated(_listbox: Gtk.ListBox, + _row: Gtk.ListBoxRow + ) -> None: app.window.show_app_page() - def _on_unread_count_changed(self, _app_page, count): + def _on_unread_count_changed(self, _app_page: AppPage, count: int) -> None: self._app_row.set_unread_count(count) class AppRow(Gtk.ListBoxRow): - def __init__(self): + def __init__(self) -> None: Gtk.ListBoxRow.__init__(self) self.get_style_context().add_class('workspace-sidebar-item') @@ -78,7 +81,7 @@ def __init__(self): self.add(overlay) self.show_all() - def set_unread_count(self, count): + def set_unread_count(self, count: int) -> None: if count < 1000: self._unread_label.set_text(str(count)) else: ===================================== gajim/gtk/avatar_selector.py ===================================== @@ -109,7 +109,7 @@ def prepare_crop_area(self, path: str) -> None: self._helper_label.hide() self._crop_area.show() - def _on_load_clicked(self, _button): + def _on_load_clicked(self, _button: Gtk.Button) -> None: def _on_file_selected(path): self.prepare_crop_area(path) @@ -117,8 +117,15 @@ def _on_file_selected(path): transient_for=self.get_toplevel(), modal=True) - def _on_drag_data_received(self, _widget, _context, _x_coord, _y_coord, - selection, target_type, _timestamp): + def _on_drag_data_received(self, + _widget: Gtk.Widget, + _context: Gdk.DragContext, + _x_coord: int, + _y_coord: int, + selection: Gtk.SelectionData, + target_type: int, + _timestamp: int + ) -> None: if not selection.get_data(): return @@ -184,10 +191,10 @@ def __init__(self) -> None: self._image = Gdk.Rectangle() self._crop = Gdk.Rectangle() - self._pixbuf = None - self._browse_pixbuf = None - self._color_shifted_pixbuf = None - self._current_cursor = None + self._pixbuf: Optional[GdkPixbuf.Pixbuf] = None + self._browse_pixbuf: Optional[GdkPixbuf.Pixbuf] = None + self._color_shifted_pixbuf: Optional[GdkPixbuf.Pixbuf] = None + self._current_cursor: Optional[Gdk.CursorType] = None self._scale = float(0.0) self._image.x = 0 @@ -259,7 +266,7 @@ def get_pixbuf(self) -> Optional[GdkPixbuf.Pixbuf]: return GdkPixbuf.Pixbuf.new_subpixbuf( self._browse_pixbuf, self._crop.x, self._crop.y, width, height) - def _on_draw(self, _widget, context): + def _on_draw(self, _widget: Gtk.Widget, context: cairo.Context) -> bool: if self._browse_pixbuf is None: return False @@ -342,7 +349,10 @@ def _on_draw(self, _widget, context): return False - def _on_button_press(self, _widget, event): + def _on_button_press(self, + _widget: Gtk.Widget, + event: Gdk.EventButton + ) -> bool: if self._browse_pixbuf is None: return False @@ -357,7 +367,10 @@ def _on_button_press(self, _widget, event): return False - def _on_button_release(self, _widget, _event): + def _on_button_release(self, + _widget: Gtk.Widget, + _event: Gdk.EventButton + ) -> bool: if self._browse_pixbuf is None: return False @@ -371,7 +384,10 @@ def _on_button_release(self, _widget, _event): return False - def _on_motion_notify(self, _widget, event): + def _on_motion_notify(self, + _widget: Gtk.Widget, + event: Gdk.EventMotion + ) -> bool: # pylint: disable=too-many-boolean-expressions # pylint: disable=too-many-branches # pylint: disable=too-many-statements @@ -565,7 +581,7 @@ def _on_motion_notify(self, _widget, event): return False - def _update_pixbufs(self): + def _update_pixbufs(self) -> None: allocation = self.get_allocation() width = self._browse_pixbuf.get_width() height = self._browse_pixbuf.get_height() @@ -625,7 +641,7 @@ def _update_pixbufs(self): self._image.width = dest_width self._image.height = dest_height - def _crop_to_widget(self): + def _crop_to_widget(self) -> Gdk.Rectangle: crop = Gdk.Rectangle() crop.x = self._image.x + self._crop.x * self._scale crop.y = self._image.y + self._crop.y * self._scale @@ -633,7 +649,7 @@ def _crop_to_widget(self): crop.height = self._crop.height * self._scale return crop - def _update_cursor(self, x_coord, y_coord): + def _update_cursor(self, x_coord: float, y_coord: float) -> None: region = self._active_region if self._active_region == Loc.OUTSIDE: crop = self._crop_to_widget() @@ -668,7 +684,12 @@ def _update_cursor(self, x_coord, y_coord): self._current_cursor = cursor_type @staticmethod - def _eval_radial_line(center_x, center_y, bounds_x, bounds_y, user_x): + def _eval_radial_line(center_x: float, + center_y: float, + bounds_x: int, + bounds_y: int, + user_x: int + ) -> int: slope_y = float(bounds_y - center_y) slope_x = bounds_x - center_x if slope_y == 0 or slope_x == 0: @@ -679,7 +700,11 @@ def _eval_radial_line(center_x, center_y, bounds_x, bounds_y, user_x): decision_intercept = - float(decision_slope * bounds_x) return int(decision_slope * user_x + decision_intercept) - def _find_location(self, rect, x_coord, y_coord): + def _find_location(self, + rect: Gdk.Rectangle, + x_coord: float, + y_coord: float + ) -> Loc: # pylint: disable=line-too-long location = [ [Loc.OUTSIDE, Loc.OUTSIDE, Loc.OUTSIDE, Loc.OUTSIDE, Loc.OUTSIDE], @@ -696,7 +721,7 @@ def _find_location(self, rect, x_coord, y_coord): return location[y_range][x_range] @staticmethod - def _find_range(coord, min_v, max_v): + def _find_range(coord: float, min_v: int, max_v: int) -> Range: tolerance = 12 if coord < min_v - tolerance: return Range.BELOW @@ -708,7 +733,7 @@ def _find_range(coord, min_v, max_v): return Range.UPPER return Range.ABOVE - def _generate_color_shifted_pixbuf(self): + def _generate_color_shifted_pixbuf(self) -> None: # pylint: disable=no-member surface = cairo.ImageSurface( cairo.Format.ARGB32, ===================================== gajim/gtk/change_password.py ===================================== @@ -12,12 +12,17 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <
http://www.gnu.org/licenses/
>. +from typing import Any +from typing import List + import logging from gi.repository import Gtk from nbxmpp.errors import StanzaError from nbxmpp.errors import ChangePasswordStanzaError +from nbxmpp.modules.dataforms import SimpleDataForm +from nbxmpp.task import Task from gajim.common import app from gajim.common.i18n import _ @@ -35,7 +40,7 @@ class ChangePassword(Assistant): - def __init__(self, account): + def __init__(self, account: str) -> None: Assistant.__init__(self) self.account = account @@ -61,7 +66,10 @@ def __init__(self, account): self.show_all() - def _on_button_clicked(self, _assistant, button_name): + def _on_button_clicked(self, + _assistant: Assistant, + button_name: str + ) -> None: page = self.get_current_page() if button_name == 'apply': self.show_page('progress', Gtk.StackTransitionType.SLIDE_LEFT) @@ -73,7 +81,7 @@ def _on_button_clicked(self, _assistant, button_name): elif button_name == 'close': self.destroy() - def _on_apply(self, next_stage=False): + def _on_apply(self, next_stage: bool = False) -> None: if next_stage: form = self.get_page('next_stage').get_submit_form() self._client.get_module('Register').change_password_with_form( @@ -84,7 +92,7 @@ def _on_apply(self, next_stage=False): password, callback=self._on_change_password) @ensure_not_destroyed - def _on_change_password(self, task): + def _on_change_password(self, task: Task) -> None: try: task.finish() except ChangePasswordStanzaError as error: @@ -101,12 +109,12 @@ def _on_change_password(self, task): passwords.save_password(self.account, password) self.show_page('success') - def _on_destroy(self, *args): + def _on_destroy(self, *args: Any) -> None: self._destroyed = True class EnterPassword(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.complete = False self.title = _('Change Password') @@ -150,7 +158,7 @@ def __init__(self): self._show_icon(False) self.show_all() - def _show_icon(self, show): + def _show_icon(self, show: bool) -> None: if show: self._password2_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, 'dialog-warning-symbolic') @@ -160,7 +168,7 @@ def _show_icon(self, show): self._password2_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) - def _on_changed(self, _entry): + def _on_changed(self, _entry: Gtk.Entry) -> None: password1 = self._password1_entry.get_text() if not password1: self._show_icon(True) @@ -175,19 +183,19 @@ def _on_changed(self, _entry): self._show_icon(False) self._set_complete(True) - def _set_complete(self, state): + def _set_complete(self, state: bool) -> None: self.complete = state self.update_page_complete() - def get_password(self): + def get_password(self) -> str: return self._password1_entry.get_text() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['apply'] class NextStage(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.set_valign(Gtk.Align.FILL) self.complete = False @@ -196,11 +204,11 @@ def __init__(self): self.show_all() - def _on_is_valid(self, _widget, is_valid): + def _on_is_valid(self, _widget: Gtk.Widget, is_valid: bool) -> None: self.complete = is_valid self.update_page_complete() - def set_form(self, form): + def set_form(self, form: SimpleDataForm) -> None: if self._current_form is not None: self.remove(self._current_form) self._current_form.destroy() @@ -210,31 +218,31 @@ def set_form(self, form): self.pack_start(self._current_form, True, True, 0) self._current_form.show_all() - def get_submit_form(self): + def get_submit_form(self) -> SimpleDataForm: return self._current_form.get_submit_form() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['apply'] class Error(ErrorPage): - def __init__(self): + def __init__(self) -> None: ErrorPage.__init__(self) self.set_title(_('Password Change Failed')) self.set_heading(_('Password Change Failed')) self.set_text( _('An error occurred while trying to change your password.')) - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['back'] class Success(SuccessPage): - def __init__(self): + def __init__(self) -> None: SuccessPage.__init__(self) self.set_title(_('Password Changed')) self.set_heading(_('Password Changed')) self.set_text(_('Your password has successfully been changed.')) - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['close'] ===================================== gajim/gtk/chat_list_stack.py ===================================== @@ -24,10 +24,10 @@ from gajim.common import app +from .chat_filter import ChatFilter from .chat_list import ChatList from .chat_list import ChatRow - HANDLED_EVENTS = [ 'message-received', 'mam-message-received', @@ -58,7 +58,10 @@ class ChatListStack(Gtk.Stack): (str, object, str)), } - def __init__(self, chat_filter, search_entry): + def __init__(self, + chat_filter: ChatFilter, + search_entry: Gtk.SearchEntry + ) -> None: Gtk.Stack.__init__(self) self.set_hexpand(True) self.set_vexpand(True) @@ -77,7 +80,7 @@ def __init__(self, chat_filter, search_entry): self._add_actions() self.show_all() - def _add_actions(self): + def _add_actions(self) -> None: actions = [ ('toggle-chat-pinned', 'as', self._toggle_chat_pinned), ('move-chat-to-workspace', 'as', self._move_chat_to_workspace), @@ -92,7 +95,7 @@ def _add_actions(self): act.connect('activate', func) app.window.add_action(act) - def _on_visible_child_name(self, _stack, _param): + def _on_visible_child_name(self, _stack: Gtk.Stack, _param: str) -> None: if self._last_visible_child_name == self.get_visible_child_name(): return @@ -125,11 +128,11 @@ def is_chat_active(self, account: str, jid: JID) -> bool: return False return chat.is_active - def _on_filter_changed(self, _filter, name): + def _on_filter_changed(self, _filter: ChatFilter, name: str) -> None: chat_list = self.get_visible_child() chat_list.set_filter(name) - def _on_search_changed(self, search_entry): + def _on_search_changed(self, search_entry: Gtk.SearchEntry) -> None: chat_list = self.get_visible_child() chat_list.set_filter_text(search_entry.get_text()) @@ -150,7 +153,10 @@ def remove_chat_list(self, workspace_id: str) -> None: self._chat_lists.pop(workspace_id) chat_list.destroy() - def _on_row_selected(self, _chat_list, row): + def _on_row_selected(self, + _chat_list: ChatList, + row: Optional[ChatRow] + ) -> None: if row is None: self.emit('chat-unselected') return @@ -188,7 +194,10 @@ def store_open_chats(self, workspace_id: str) -> None: app.settings.set_workspace_setting( workspace_id, 'open_chats', open_chats) - def _toggle_chat_pinned(self, _action, param): + def _toggle_chat_pinned(self, + _action: Gio.SimpleAction, + param: GLib.Variant + ) -> None: workspace_id, account, jid = param.unpack() jid = JID.from_string(jid) @@ -196,7 +205,10 @@ def _toggle_chat_pinned(self, _action, param): chat_list.toggle_chat_pinned(account, jid) self.store_open_chats(workspace_id) - def _move_chat_to_workspace(self, _action, param): + def _move_chat_to_workspace(self, + _action: Gio.SimpleAction, + param: GLib.Variant + ) -> None: new_workspace_id, account, jid = param.unpack() jid = JID.from_string(jid) @@ -209,7 +221,10 @@ def _move_chat_to_workspace(self, _action, param): self.store_open_chats(current_chatlist.workspace_id) self.store_open_chats(new_workspace_id) - def _mark_as_read(self, _action, param): + def _mark_as_read(self, + _action: Gio.SimpleAction, + param: GLib.Variant + ) -> None: _workspace_id, account, jid = param.unpack() self.mark_as_read(account, JID.from_string(jid)) View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/0f1e4c61117b5f60e68e91f4bcd1936…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/0f1e4c61117b5f60e68e91f4bcd1936…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] 4 commits: AddContact: Typing
by Daniel Brötzmann (@wurstsalat)
22 Dec '21
22 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: e348faf6 by wurstsalat at 2021-12-22T19:27:38+01:00 AddContact: Typing - - - - - 211e49ee by wurstsalat at 2021-12-22T19:28:32+01:00 AddContact: Make sure Contact can be added under any circumstances - - - - - 1ad8eddc by wurstsalat at 2021-12-22T19:46:46+01:00 Assistant: Typing - - - - - 0f1e4c61 by wurstsalat at 2021-12-22T19:57:54+01:00 AdvancedConfig: Typing - - - - - 4 changed files: - gajim/common/app.py - gajim/gtk/add_contact.py - gajim/gtk/advanced_config.py - gajim/gtk/assistant.py Changes: ===================================== gajim/common/app.py ===================================== @@ -399,12 +399,12 @@ def get_accounts_sorted() -> list[str]: def get_enabled_accounts_with_labels( exclude_local: bool = True, connected_only: bool = False, - private_storage_only: bool = False) -> list[str]: + private_storage_only: bool = False) -> list[list[str]]: """ Returns a list with [account, account_label] entries. Order by account_label """ - accounts: list[str] = [] + accounts = [] for acc in connections: if exclude_local and account_is_zeroconf(acc): continue ===================================== gajim/gtk/add_contact.py ===================================== @@ -12,9 +12,12 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <
http://www.gnu.org/licenses/
>. -from typing import Tuple -from typing import Optional from typing import Any +from typing import Dict +from typing import List +from typing import Optional +from typing import Tuple +from typing import Union import logging @@ -23,8 +26,11 @@ from nbxmpp import JID from nbxmpp import Namespace from nbxmpp.errors import is_error +from nbxmpp.errors import StanzaError +from nbxmpp.structs import DiscoInfo from gajim.common import app +from gajim.common import types from gajim.common.helpers import get_subscription_request_msg from gajim.common.helpers import validate_jid from gajim.common.i18n import _ @@ -45,13 +51,13 @@ class AddContact(Assistant): def __init__(self, account: Optional[str] = None, jid: Optional[JID] = None, - nick: str = None): + nick: Optional[str] = None): Assistant.__init__(self) self.account = account self.jid = jid self._nick = nick - self._result = None + self._result: Union[DiscoInfo, StanzaError, None] = None self.add_button('next', _('Next'), complete=True, css_class='suggested-action') @@ -74,14 +80,17 @@ def __init__(self, progress.set_text(_('Trying to gather information on this address…')) self.connect('button-clicked', self._on_button_clicked) + self.connect('destroy', self._on_destroy) self.show_all() - self.connect('destroy', self._on_destroy) - def _on_destroy(self, *args): + def _on_destroy(self, *args: Any) -> None: app.check_finalize(self) - def _on_button_clicked(self, _assistant, button_name): + def _on_button_clicked(self, + _assistant: Assistant, + button_name: str + ) -> None: page = self.get_current_page() account, _ = self.get_page('address').get_account_and_jid() @@ -126,7 +135,7 @@ def _start_disco(self) -> None: self._disco_info(account, jid) @as_task - def _disco_info(self, account, address): + def _disco_info(self, account: str, address: str) -> None: _task = yield client = app.get_client(account) @@ -139,7 +148,7 @@ def _disco_info(self, account, address): log.info('Disco Info received: %s', address) self._process_info(account, result) - def _process_error(self, account, result): + def _process_error(self, account: str, result: StanzaError) -> None: log.debug('Error received: %s', result) self._result = result @@ -155,7 +164,7 @@ def _process_error(self, account, result): self.get_page('error').set_text(result.get_text()) self.show_page('error', Gtk.StackTransitionType.SLIDE_LEFT) - def _process_info(self, account, result): + def _process_info(self, account: str, result: DiscoInfo) -> None: log.debug('Info received: %s', result) self._result = result @@ -186,14 +195,8 @@ def _process_info(self, account, result): self.show_page('gateway', Gtk.StackTransitionType.SLIDE_LEFT) return - if result.has_category('client'): - self.get_page('contact').prepare(account, result) - self.show_page('contact', Gtk.StackTransitionType.SLIDE_LEFT) - return - - self.get_page('error').set_text( - _('This address does not seem to offer any gateway service.')) - self.show_page('error') + self.get_page('contact').prepare(account, result) + self.show_page('contact', Gtk.StackTransitionType.SLIDE_LEFT) class Address(Page): @@ -218,12 +221,12 @@ def __init__(self, account: Optional[str], jid: Optional[JID]) -> None: if len(accounts) > 1: self._ui.account_box.show() - if self._account is not None: + if account is not None: self._ui.account_combo.set_active_id(account) else: self._ui.account_combo.set_active(0) else: - # Set to first (and only) item; sets self._account as well + # Set to first (and only) item; sets self._account automatically self._ui.account_combo.set_active(0) if jid is not None: @@ -233,29 +236,29 @@ def __init__(self, account: Optional[str], jid: Optional[JID]) -> None: self.show_all() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['next'] - def get_default_button(self): + def get_default_button(self) -> str: return 'next' - def get_account_and_jid(self) -> Tuple[Optional[str], Any]: + def get_account_and_jid(self) -> Tuple[str, str]: return self._account, self._ui.address_entry.get_text() def focus(self) -> None: self._ui.address_entry.grab_focus() - def _on_account_changed(self, combobox): + def _on_account_changed(self, combobox: Gtk.ComboBox) -> None: account = combobox.get_active_id() self._account = account self._set_complete() - def _show_icon(self, show): + def _show_icon(self, show: bool) -> None: icon = 'dialog-warning-symbolic' if show else None self._ui.address_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, icon) - def _set_complete(self, *args): + def _set_complete(self, *args: Any) -> None: if self._account is None: self.complete = False self.update_page_complete() @@ -306,26 +309,26 @@ def _validate_address(self, address: str) -> bool: class Error(ErrorPage): - def __init__(self): + def __init__(self) -> None: ErrorPage.__init__(self) self.set_title(_('Add Contact')) self.set_heading(_('An Error Occurred')) - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['back'] - def get_default_button(self): + def get_default_button(self) -> str: return 'back' class Contact(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.title = _('Add Contact') - self._result = None - self._account = None - self._contact = None + self._result: Union[DiscoInfo, StanzaError, None] = None + self._account: Optional[str] = None + self._contact: Optional[types.BareContact] = None self._ui = get_builder('add_contact.ui') self.add(self._ui.contact_grid) @@ -334,13 +337,13 @@ def __init__(self): self.show_all() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['back', 'add'] - def get_default_button(self): + def get_default_button(self) -> str: return 'add' - def prepare(self, account, result): + def prepare(self, account: str, result: Union[DiscoInfo, StanzaError]): self._result = result self._account = account @@ -357,11 +360,11 @@ def _update_groups(self, account: str) -> None: for group in client.get_module('Roster').get_groups(): self._ui.group_combo.append_text(group) - def _on_info_clicked(self, _button): + def _on_info_clicked(self, _button: Gtk.Button) -> None: open_window( 'ContactInfo', account=self._account, contact=self._contact) - def get_subscription_data(self): + def get_subscription_data(self) -> Dict[str, Union[str, List[str], bool]]: group = self._ui.group_combo.get_child().get_text() groups = [group] if group else [] return { @@ -372,12 +375,12 @@ def get_subscription_data(self): class Gateway(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.title = _('Service Gateway') - self._account = None - self._result = None + self._account: Optional[str] = None + self._result: Optional[DiscoInfo] = None self._ui = get_builder('add_contact.ui') self.add(self._ui.gateway_box) @@ -387,13 +390,13 @@ def __init__(self): self.show_all() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['back', 'add'] - def get_default_button(self): + def get_default_button(self) -> str: return 'add' - def prepare(self, account, result): + def prepare(self, account: str, result: DiscoInfo) -> None: self._account = account self._result = result @@ -447,22 +450,22 @@ def prepare(self, account, result): self._ui.commands_button.set_tooltip_text( _('This gateway does not support Ad-Hoc Commands.')) - def _on_register_clicked(self, _button): + def _on_register_clicked(self, _button: Gtk.Button) -> None: open_window( 'ServiceRegistration', account=self._account, address=self._result.jid) - def _on_command_clicked(self, _button): + def _on_command_clicked(self, _button: Gtk.Button) -> None: AdHocCommand(self._account, self._result.jid) class GroupChat(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self.title = _('Join Group Chat?') - self._result = None + self._result: Optional[DiscoInfo] = None heading = Gtk.Label(label=_('Join Group Chat?')) heading.get_style_context().add_class('large-header') @@ -477,13 +480,13 @@ def __init__(self): self.show_all() - def get_visible_buttons(self): + def get_visible_buttons(self) -> List[str]: return ['back', 'join'] - def get_default_button(self): + def get_default_button(self) -> str: return 'join' - def prepare(self, account, result): + def prepare(self, account: str, result: DiscoInfo) -> None: self._result = result self._info_box.set_account(account) ===================================== gajim/gtk/advanced_config.py ===================================== @@ -19,6 +19,8 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <
http://www.gnu.org/licenses/
>. +from typing import Optional + from enum import IntEnum from enum import unique @@ -32,6 +34,7 @@ from gajim.common.setting_values import ADVANCED_SETTINGS from gajim.common.setting_values import APP_SETTINGS + from .builder import get_builder @@ -56,7 +59,7 @@ class Column(IntEnum): class AdvancedConfig(Gtk.ApplicationWindow): - def __init__(self): + def __init__(self) -> None: Gtk.ApplicationWindow.__init__(self) self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) @@ -107,7 +110,7 @@ def __init__(self): self._ui.connect_signals(self) self.show_all() - def _on_key_press(self, _widget, event): + def _on_key_press(self, _widget: Gtk.Widget, event: Gdk.EventKey) -> None: if event.keyval != Gdk.KEY_Escape: return @@ -117,11 +120,18 @@ def _on_key_press(self, _widget, event): self.destroy() - def _value_column_data_callback(self, _col, cell, model, iter_, _data): + def _value_column_data_callback(self, + _col: Gtk.TreeViewColumn, + cell: Gtk.CellRenderer, + model: Gtk.TreeModel, + iter_: Gtk.TreeIter, + _data: Optional[object]): opttype = model[iter_][Column.TYPE] cell.set_property('editable', opttype != SETTING_TYPES[bool]) - def _on_treeview_selection_changed(self, treeselection): + def _on_treeview_selection_changed(self, + treeselection: Gtk.TreeSelection + ) -> None: model, iter_ = treeselection.get_selected() if not iter_: self._ui.reset_button.set_sensitive(False) @@ -133,7 +143,11 @@ def _on_treeview_selection_changed(self, treeselection): self._ui.description.set_text(desc or Q_('?config description:None')) self._ui.reset_button.set_sensitive(True) - def _on_treeview_row_activated(self, _treeview, path, _column): + def _on_treeview_row_activated(self, + _treeview: Gtk.TreeView, + path: Gtk.TreePath, + _column: Gtk.TreeViewColumn + ) -> None: modelpath = self.modelfilter.convert_path_to_child_path(path) modelrow = self.model[modelpath] setting = modelrow[Column.NAME] @@ -147,7 +161,11 @@ def _on_treeview_row_activated(self, _treeview, path, _column): app.settings.set(setting, setting_value) modelrow[Column.VALUE] = column_value - def _on_config_edited(self, _cell, path, text): + def _on_config_edited(self, + _cell: Gtk.CellRendererText, + path: str, + text: str + ) -> None: path = Gtk.TreePath.new_from_string(path) modelpath = self.modelfilter.convert_path_to_child_path(path) modelrow = self.model[modelpath] @@ -160,7 +178,7 @@ def _on_config_edited(self, _cell, path, text): app.settings.set(setting, value) modelrow[Column.VALUE] = text - def _on_reset_button_clicked(self, button): + def _on_reset_button_clicked(self, button: Gtk.Button) -> None: model, iter_ = self.treeview.get_selection().get_selected() if not iter_: return @@ -176,7 +194,7 @@ def _on_reset_button_clicked(self, button): app.settings.set(setting, default) button.set_sensitive(False) - def _fill_model(self, node=None, parent=None): + def _fill_model(self, parent=None) -> None: for category, settings in ADVANCED_SETTINGS.items(): if category != 'app': continue @@ -199,7 +217,11 @@ def _fill_model(self, node=None, parent=None): self.model.append(parent, [setting, value, type_]) - def _visible_func(self, model, treeiter, _data): + def _visible_func(self, + model: Gtk.TreeModel, + treeiter: Gtk.TreeIter, + _data: Optional[object] + ) -> bool: search_string = self._ui.search_entry.get_text().lower() if not search_string: return True @@ -211,5 +233,5 @@ def _visible_func(self, model, treeiter, _data): return True return False - def _on_search_entry_changed(self, _widget): + def _on_search_entry_changed(self, _entry: Gtk.SearchEntry) -> None: self.modelfilter.refilter() ===================================== gajim/gtk/assistant.py ===================================== @@ -12,6 +12,12 @@ # 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 Any +from typing import Dict +from typing import Optional +from typing import Tuple + from gi.repository import Gdk from gi.repository import Gtk from gi.repository import Gio @@ -36,10 +42,10 @@ class Assistant(Gtk.ApplicationWindow, EventHelper): )) def __init__(self, - transient_for=None, - width=550, - height=400, - transition_duration=200): + transient_for: Optional[Gtk.Window] = None, + width: int = 550, + height: int = 400, + transition_duration: int = 200) -> None: Gtk.ApplicationWindow.__init__(self) EventHelper.__init__(self) self.set_application(Gio.Application.get_default()) @@ -51,8 +57,8 @@ def __init__(self, self.set_transient_for(transient_for) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) - self._pages = {} - self._buttons = {} + self._pages: Dict[str, Page] = {} + self._buttons: Dict[str, Tuple[Gtk.Button, bool]] = {} self._button_visible_func = None self._ui = get_builder('assistant.ui') @@ -64,29 +70,32 @@ def __init__(self, self.connect('destroy', self.__on_destroy) self._ui.connect_signals(self) - def show_all(self): + def show_all(self) -> None: page_name = self._ui.stack.get_visible_child_name() self.emit('page-changed', page_name) Gtk.ApplicationWindow.show_all(self) - def _on_key_press_event(self, _widget, event): + def _on_key_press_event(self, + _widget: Gtk.Widget, + event: Gdk.EventKey + ) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy() - def _update_page_complete(self, *args): + def _update_page_complete(self, *args: Any) -> None: page_widget = self._ui.stack.get_visible_child() for button, complete in self._buttons.values(): if complete: button.set_sensitive(page_widget.complete) - def update_title(self): + def update_title(self) -> None: self.set_title(self._ui.stack.get_visible_child().title) - def _hide_buttons(self): + def _hide_buttons(self) -> None: for button, _ in self._buttons.values(): button.hide() - def _set_buttons_visible(self): + def _set_buttons_visible(self) -> None: page_name = self._ui.stack.get_visible_child_name() if self._button_visible_func is None: buttons = self.get_page(page_name).get_visible_buttons() @@ -112,11 +121,16 @@ def _set_buttons_visible(self): def set_button_visible_func(self, func): self._button_visible_func = func - def set_default_button(self, button_name): + def set_default_button(self, button_name: str) -> None: button, _ = self._buttons[button_name] button.grab_default() - def add_button(self, name, label, css_class=None, complete=False): + def add_button(self, + name: str, + label: str, + css_class: Optional[str] = None, + complete: bool = False + ) -> None: button = Gtk.Button(label=label, can_default=True, no_show_all=True) @@ -126,13 +140,13 @@ def add_button(self, name, label, css_class=None, complete=False): self._buttons[name] = (button, complete) self._ui.action_area.pack_end(button, False, False, 0) - def add_pages(self, pages): + def add_pages(self, pages: Dict[str, Page]): self._pages = pages for name, widget in pages.items(): widget.connect('update-page-complete', self._update_page_complete) self._ui.stack.add_named(widget, name) - def add_default_page(self, name): + def add_default_page(self, name: str) -> Page: if name == 'success': page = SuccessPage() elif name == 'error': @@ -146,19 +160,22 @@ def add_default_page(self, name): self._ui.stack.add_named(page, name) return page - def get_current_page(self): + def get_current_page(self) -> str: return self._ui.stack.get_visible_child_name() - def show_page(self, name, transition=Gtk.StackTransitionType.NONE): + def show_page(self, + name: str, + transition: Gtk.StackTransitionType = Gtk.StackTransitionType.NONE + ) -> None: if self._ui.stack.get_visible_child_name() == name: return self._hide_buttons() self._ui.stack.set_visible_child_full(name, transition) - def get_page(self, name): + def get_page(self, name: str) -> Page: return self._pages[name] - def _on_visible_child_name(self, stack, _param): + def _on_visible_child_name(self, stack: Gtk.Stack, _param: str) -> None: if stack.get_visible_child_name() is None: # Happens for some reason when adding the first page return @@ -166,14 +183,14 @@ def _on_visible_child_name(self, stack, _param): self._set_buttons_visible() self.emit('page-changed', stack.get_visible_child_name()) - def __on_button_clicked(self, button): + def __on_button_clicked(self, button: Gtk.Button) -> None: for button_name, button_data in self._buttons.items(): button_ = button_data[0] if button_ == button: self.emit('button-clicked', button_name) return - def __on_destroy(self, *args): + def __on_destroy(self, *args: Any) -> None: self._pages.clear() self._buttons.clear() @@ -184,26 +201,26 @@ class Page(Gtk.Box): 'update-page-complete': (GObject.SignalFlags.RUN_LAST, None, ()), } - def __init__(self): + def __init__(self) -> None: Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.set_spacing(18) self.set_valign(Gtk.Align.CENTER) - self.title = '' - self.complete = True + self.title: str = '' + self.complete: bool = True - def get_visible_buttons(self): + def get_visible_buttons(self) -> None: return None - def get_default_button(self): + def get_default_button(self) -> None: return None - def update_page_complete(self): + def update_page_complete(self) -> None: self.emit('update-page-complete') class DefaultPage(Page): - def __init__(self, icon_name, icon_css_class): + def __init__(self, icon_name: str, icon_css_class: str) -> None: Page.__init__(self) self._heading = Gtk.Label() @@ -227,32 +244,32 @@ def __init__(self, icon_name, icon_css_class): self.pack_start(self._label, False, True, 0) self.show_all() - def set_heading(self, heading): + def set_heading(self, heading: str) -> None: self._heading.set_text(heading) - def set_text(self, text): + def set_text(self, text: str) -> None: self._label.set_text(text) - def set_title(self, title): + def set_title(self, title: str) -> None: self.title = title class ErrorPage(DefaultPage): - def __init__(self): + def __init__(self) -> None: DefaultPage.__init__(self, icon_name='dialog-error-symbolic', icon_css_class='error-color') class SuccessPage(DefaultPage): - def __init__(self): + def __init__(self) -> None: DefaultPage.__init__(self, icon_name='object-select-symbolic', icon_css_class='success-color') class ProgressPage(Page): - def __init__(self): + def __init__(self) -> None: Page.__init__(self) self._label = Gtk.Label() @@ -269,8 +286,8 @@ def __init__(self): self.show_all() - def set_text(self, text): + def set_text(self, text: str) -> None: self._label.set_text(text) - def set_title(self, title): + def set_title(self, title: str) -> None: self.title = title View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/36d4071a8ade991b562b6832da20b1f…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/36d4071a8ade991b562b6832da20b1f…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] ManageSounds: Typing
by Daniel Brötzmann (@wurstsalat)
22 Dec '21
22 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: 36d4071a by wurstsalat at 2021-12-22T10:43:56+01:00 ManageSounds: Typing - - - - - 1 changed file: - gajim/gtk/manage_sounds.py Changes: ===================================== gajim/gtk/manage_sounds.py ===================================== @@ -27,7 +27,7 @@ class ManageSounds(Gtk.ApplicationWindow): - def __init__(self, transient_for): + def __init__(self, transient_for: Gtk.Window) -> None: Gtk.ApplicationWindow.__init__(self) self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) @@ -61,7 +61,10 @@ def __init__(self, transient_for): self.show_all() @staticmethod - def _on_row_changed(model, path, iter_): + def _on_row_changed(model: Gtk.TreeModel, + path: Gtk.TreePath, + iter_: Gtk.TreeIter + ) -> None: sound_event = model[iter_][3] app.settings.set_soundevent_setting(sound_event, 'enabled', @@ -70,17 +73,19 @@ def _on_row_changed(model, path, iter_): 'path', model[iter_][2]) - def _on_toggle(self, _cell, path): + def _on_toggle(self, + _cell: Gtk.CellRendererToggle, + path: Gtk.TreePath + ) -> None: if self._ui.filechooser.get_filename() is None: return model = self._ui.sounds_treeview.get_model() model[path][0] = not model[path][0] - def _fill_sound_treeview(self): + def _fill_sound_treeview(self) -> None: model = self._ui.sounds_treeview.get_model() model.clear() - # pylint: disable=line-too-long sounds_dict = { 'attention_received': _('Attention Message Received'), 'first_message_received': _('Message Received'), @@ -90,7 +95,6 @@ def _fill_sound_treeview(self): 'muc_message_highlight': _('Group Chat Message Highlight'), 'muc_message_received': _('Group Chat Message Received'), } - # pylint: enable=line-too-long for sound_event, sound_name in sounds_dict.items(): settings = app.settings.get_soundevent_settings(sound_event) @@ -99,7 +103,7 @@ def _fill_sound_treeview(self): settings['path'], sound_event)) - def _on_cursor_changed(self, treeview): + def _on_cursor_changed(self, treeview: Gtk.TreeView) -> None: model, iter_ = treeview.get_selection().get_selected() path_to_snd_file = check_soundfile_path(model[iter_][2]) if path_to_snd_file is None: @@ -107,7 +111,7 @@ def _on_cursor_changed(self, treeview): else: self._ui.filechooser.set_filename(str(path_to_snd_file)) - def _on_file_set(self, button): + def _on_file_set(self, button: Gtk.FileChooserButton) -> None: model, iter_ = self._ui.sounds_treeview.get_selection().get_selected() filename = button.get_filename() @@ -120,17 +124,17 @@ def _on_file_set(self, button): # set the sound to enabled model[iter_][0] = True - def _on_clear(self, *args): + def _on_clear(self, _button: Gtk.Button) -> None: self._ui.filechooser.unselect_all() model, iter_ = self._ui.sounds_treeview.get_selection().get_selected() model[iter_][2] = '' model[iter_][0] = False - def _on_play(self, *args): + def _on_play(self, _button: Gtk.Button) -> None: model, iter_ = self._ui.sounds_treeview.get_selection().get_selected() snd_event_config_name = model[iter_][3] play_sound(snd_event_config_name, None, force=True) - def _on_key_press(self, _widget, event): + def _on_key_press(self, _widget: Gtk.Widget, event: Gdk.EventKey) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy() View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/36d4071a8ade991b562b6832da20b1f4…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/36d4071a8ade991b562b6832da20b1f4…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] 2 commits: BaseControl: Simplify _allow_add_message
by Daniel Brötzmann (@wurstsalat)
21 Dec '21
21 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: ed997562 by wurstsalat at 2021-12-22T00:33:36+01:00 BaseControl: Simplify _allow_add_message - - - - - e0e263ef by wurstsalat at 2021-12-22T00:34:56+01:00 BaseControl: Disable reducing message count for now - - - - - 1 changed file: - gajim/gtk/controls/base.py Changes: ===================================== gajim/gtk/controls/base.py ===================================== @@ -1128,9 +1128,7 @@ def save_message(self, message: str, msg_type: str) -> None: def _allow_add_message(self) -> bool: # Only add messages if the view is already populated - chat_loaded = app.window.is_chat_loaded(self.account, self.contact.jid) - lower_complete = self._scrolled_view.get_lower_complete() - return chat_loaded and lower_complete + return self.is_chat_loaded and self._scrolled_view.get_lower_complete() def add_info_message(self, text: str) -> None: self.conversation_view.add_info_message(text) @@ -1321,7 +1319,6 @@ def update_text_tags(self): def set_control_active(self, state: bool) -> None: if not self._chat_loaded: self.fetch_n_lines_history(self._scrolled_view, True, 20) - self._chat_loaded = True if state: self.set_emoticon_popover() @@ -1402,6 +1399,8 @@ def fetch_n_lines_history(self, timestamp, n_lines) + self._chat_loaded = True + if not messages: self._scrolled_view.set_history_complete(before, True) self.conversation_view.unlock() @@ -1412,9 +1411,9 @@ def fetch_n_lines_history(self, if len(messages) < n_lines: self._scrolled_view.set_history_complete(before, True) - if self._scrolled_view.get_autoscroll(): - if self.conversation_view.reduce_message_count(before): - self._scrolled_view.set_history_complete(before, False) + # if self._scrolled_view.get_autoscroll(): + # if self.conversation_view.reduce_message_count(before): + # self._scrolled_view.set_history_complete(before, False) self.conversation_view.unlock() View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/528aae4763759fc81fb305cbfa62a02…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/528aae4763759fc81fb305cbfa62a02…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] Add chats to default workspace unless explicitly opened
by Daniel Brötzmann (@wurstsalat)
21 Dec '21
21 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: 528aae47 by wurstsalat at 2021-12-22T00:25:45+01:00 Add chats to default workspace unless explicitly opened - - - - - 3 changed files: - gajim/gtk/controls/groupchat.py - gajim/gtk/main.py - gajim/gtk/start_chat.py Changes: ===================================== gajim/gtk/controls/groupchat.py ===================================== @@ -683,7 +683,8 @@ def _on_roster_row_activated(self, _roster, nick): app.window.add_chat(self.account, participant.real_jid.bare, 'contact', - select=True) + select=True, + workspace='current') else: contact = self.contact.get_resource(nick) app.window.add_private_chat(self.account, contact.jid, select=True) ===================================== gajim/gtk/main.py ===================================== @@ -450,10 +450,15 @@ def _add_chat(self, account, jid, type_, select = param.unpack() self.add_chat(account, JID.from_string(jid), type_, select) - def add_chat(self, account: str, jid: JID, type_: str, - select: bool = False) -> None: - workspace_id = self.get_active_workspace() - if workspace_id is None: + def add_chat(self, + account: str, + jid: JID, + type_: str, + select: bool = False, + workspace: str = 'default') -> None: + if workspace == 'current': + workspace_id = self.get_active_workspace() + else: workspace_id = self._workspace_side_bar.get_first_workspace() self._chat_page.add_chat_for_workspace(workspace_id, account, ===================================== gajim/gtk/start_chat.py ===================================== @@ -338,7 +338,12 @@ def _start_new_chat(self, row): self._disco_muc(row.account, jid, request_vcard=row.new) else: - app.window.add_chat(row.account, jid, 'contact', select=True) + app.window.add_chat( + row.account, + jid, + 'contact', + select=True, + workspace='current') self.ready_to_destroy = True self.destroy() View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/528aae4763759fc81fb305cbfa62a026…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/528aae4763759fc81fb305cbfa62a026…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] Make console output more quiet
by Philipp Hörist (@lovetox)
21 Dec '21
21 Dec '21
Philipp Hörist pushed to branch master at gajim / gajim Commits: d00660fc by lovetox at 2021-12-21T23:48:19+01:00 Make console output more quiet - - - - - 2 changed files: - gajim/common/logging_helpers.py - gajim/common/modules/vcard_avatars.py Changes: ===================================== gajim/common/logging_helpers.py ===================================== @@ -163,7 +163,7 @@ def init(): root_log.propagate = False root_log = logging.getLogger('nbxmpp') - root_log.setLevel(logging.WARNING) + root_log.setLevel(logging.CRITICAL) root_log.addHandler(consoleloghandler) root_log.propagate = False ===================================== gajim/common/modules/vcard_avatars.py ===================================== @@ -60,7 +60,7 @@ def _request_vcard(self, jid, expected_sha, type_): avatar, avatar_sha = vcard.get_avatar() if avatar is None: - self._log.warning('Avatar missing: %s %s', jid, expected_sha) + self._log.info('Avatar missing: %s %s', jid, expected_sha) return if expected_sha != avatar_sha: View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/d00660fc99b83b0239e9bd3504c06fd7…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/d00660fc99b83b0239e9bd3504c06fd7…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] View: Destroy rows after removing
by Philipp Hörist (@lovetox)
21 Dec '21
21 Dec '21
Philipp Hörist pushed to branch master at gajim / gajim Commits: 7fe0851d by lovetox at 2021-12-21T22:26:16+01:00 View: Destroy rows after removing - - - - - 1 changed file: - gajim/gtk/conversation/view.py Changes: ===================================== gajim/gtk/conversation/view.py ===================================== @@ -508,3 +508,7 @@ def decline_call(self, event): def _on_contact_setting_changed(self, *args): self.invalidate_filter() + + def remove(self, widget: Gtk.Widget) -> None: + super().remove(widget) + widget.destroy() View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/7fe0851dd1f857139a40b958e91037de…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/7fe0851dd1f857139a40b958e91037de…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] CertStore: Add type annotations
by Philipp Hörist (@lovetox)
21 Dec '21
21 Dec '21
Philipp Hörist pushed to branch master at gajim / gajim Commits: 6670992e by lovetox at 2021-12-21T21:39:16+01:00 CertStore: Add type annotations - - - - - 3 changed files: - gajim/common/cert_store.py - gajim/common/helpers.py - pyrightconfig.json Changes: ===================================== gajim/common/cert_store.py ===================================== @@ -12,8 +12,11 @@ # 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 import logging +from pathlib import Path +from typing import Optional from gi.repository import GLib from gi.repository import Gio @@ -30,18 +33,18 @@ class CertificateStore: def __init__(self): self._path = configpaths.get('CERT_STORE') - self._certs = [] + self._certs: list[Gio.TlsCertificate] = [] self._load_certificates() - def _get_random_path(self): + def _get_random_path(self) -> Path: filename = get_random_string() path = self._path / filename if path.exists(): return self._get_random_path() return path - def _load_certificates(self): + def _load_certificates(self) -> None: for path in self._path.iterdir(): if path.is_dir(): continue @@ -59,7 +62,7 @@ def _load_certificates(self): def get_certificates(self): return list(self._certs) - def add_certificate(self, certificate): + def add_certificate(self, certificate: Gio.TlsCertificate) -> None: log.info('Add certificate to trust store') self._certs.append(certificate) pem = certificate.props.certificate_pem @@ -69,7 +72,10 @@ def add_certificate(self, certificate): self._on_certificate_write_finished, path) - def verify(self, certificate, tls_errors): + def verify(self, + certificate: Gio.TlsCertificate, + tls_errors: set[Gio.TlsCertificateFlags]): + if Gio.TlsCertificateFlags.UNKNOWN_CA in tls_errors: for trusted_certificate in self._certs: if trusted_certificate.is_same(certificate): @@ -81,9 +87,11 @@ def verify(self, certificate, tls_errors): return False @staticmethod - def _on_certificate_write_finished(data, error, path): - if data is None: - log.error('Can\'t store certificate: %s', error) + def _on_certificate_write_finished(_successful: bool, + error: Optional[GLib.Error], + path: Path): + if error is not None: + log.error('Can\'t store certificate: %s', error.message) return log.info('Certificate stored: %s', path) ===================================== gajim/common/helpers.py ===================================== @@ -28,6 +28,7 @@ from __future__ import annotations from typing import Any +from typing import Callable from typing import Dict from typing import Optional from typing import List @@ -1256,7 +1257,12 @@ def notify(self, signal_name: str, *args: Any, **kwargs: Any): func(self, signal_name, *args, **kwargs) -def write_file_async(path, data, callback, user_data=None): +def write_file_async( + path: Path, + data: bytes, + callback: Callable[[bool, Optional[GLib.Error], Any], Any], + user_data: Optional[Any] = None): + file = Gio.File.new_for_path(str(path)) file.create_async(Gio.FileCreateFlags.PRIVATE, GLib.PRIORITY_DEFAULT, ===================================== pyrightconfig.json ===================================== @@ -11,6 +11,7 @@ ], "typeCheckingMode": "strict", "include": [ - "gajim/gtk/chat_filter.py" + "gajim/gtk/chat_filter.py", + "gajim/common/cert_store.py" ], } View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/6670992e9fbff38f7e1b12ce1c65f77f…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/6670992e9fbff38f7e1b12ce1c65f77f…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] Settings: Add missing comma
by Philipp Hörist (@lovetox)
21 Dec '21
21 Dec '21
Philipp Hörist pushed to branch master at gajim / gajim Commits: 5b2cf12f by lovetox at 2021-12-21T20:05:45+01:00 Settings: Add missing comma - - - - - 1 changed file: - gajim/common/setting_values.py Changes: ===================================== gajim/common/setting_values.py ===================================== @@ -108,7 +108,7 @@ class _ACCOUNT_DEFAULT: 'mainwin_y_position', 'notification_position_x', 'notification_position_y', - 'preview_max_file_size' + 'preview_max_file_size', 'preview_size', 'restore_timeout', ] @@ -134,7 +134,7 @@ class _ACCOUNT_DEFAULT: 'muclumbus_api_http_uri', 'muclumbus_api_jid', 'muclumbus_api_pref', - 'preview_leftclick_action' + 'preview_leftclick_action', 'roster_theme', 'search_engine', 'show_main_window_on_startup', View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/5b2cf12f126d8c0b52890a16042ba3ff…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/commit/5b2cf12f126d8c0b52890a16042ba3ff…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
[Git][gajim/gajim][master] 2 commits: CSSConfig: Typing
by Daniel Brötzmann (@wurstsalat)
21 Dec '21
21 Dec '21
Daniel Brötzmann pushed to branch master at gajim / gajim Commits: 5581a800 by wurstsalat at 2021-12-21T19:20:05+01:00 CSSConfig: Typing - - - - - 2a337add by wurstsalat at 2021-12-21T19:20:05+01:00 Themes: Typing - - - - - 2 changed files: - gajim/gtk/css_config.py - gajim/gtk/themes.py Changes: ===================================== gajim/gtk/css_config.py ===================================== @@ -15,8 +15,14 @@ # 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 Optional +from typing import Union +from typing import Tuple + import math import logging +from pathlib import Path from gi.repository import Gtk from gi.repository import Gdk @@ -33,8 +39,8 @@ settings = Gtk.Settings.get_default() -class CSSConfig(): - def __init__(self): +class CSSConfig: + def __init__(self) -> None: """ CSSConfig handles loading and storing of all relevant Gajim style files @@ -69,24 +75,24 @@ def __init__(self): css_parser.ser.prefs.keepEmptyRules = False # Holds the currently selected theme in the Theme Editor - self._pre_css = None - self._pre_css_path = None + self._pre_css: Optional[css_parser.css.CSSStyleSheet] = None + self._pre_css_path: Optional[Path] = None # Holds the default theme, its used if values are not found # in the selected theme - self._default_css = None - self._default_css_path = None + self._default_css: Optional[css_parser.css.CSSStyleSheet] = None + self._default_css_path: Optional[Path] = None # Holds the currently selected theme - self._css = None - self._css_path = None + self._css: Optional[css_parser.css.CSSStyleSheet] = None + self._css_path: Optional[Path] = None # User Theme CSS Provider self._provider = Gtk.CssProvider() # Used for dynamic classes like account colors self._dynamic_provider = Gtk.CssProvider() - self._dynamic_dict = {} + self._dynamic_dict: dict[str, str] = {} self.refresh() Gtk.StyleContext.add_provider_for_screen( @@ -95,10 +101,10 @@ def __init__(self): CSSPriority.APPLICATION) # Cache of recently requested values - self._cache = {} + self._cache: dict[str, Union[str, Pango.FontDescription, None]] = {} # Holds all currently available themes - self.themes = [] + self.themes: list[str] = [] self.set_dark_theme() self._load_css() @@ -113,7 +119,7 @@ def __init__(self): CSSPriority.USER_THEME) @property - def prefer_dark(self): + def prefer_dark(self) -> bool: setting = app.settings.get('dark_theme') if setting == Theme.SYSTEM: if settings is None: @@ -121,7 +127,7 @@ def prefer_dark(self): return settings.get_property('gtk-application-prefer-dark-theme') return setting == Theme.DARK - def set_dark_theme(self, value=None): + def set_dark_theme(self, value: Optional[int] = None) -> None: if value is None: value = app.settings.get('dark_theme') else: @@ -135,7 +141,7 @@ def set_dark_theme(self, value=None): settings.set_property('gtk-application-prefer-dark-theme', bool(value)) self._load_css() - def _load_css(self): + def _load_css(self) -> None: self._load_css_from_file('gajim.css', CSSPriority.APPLICATION) if self.prefer_dark: self._load_css_from_file('gajim-dark.css', @@ -146,7 +152,10 @@ def _load_css(self): self._load_css_from_file('default-dark.css', CSSPriority.DEFAULT_THEME_DARK) - def _load_css_from_file(self, filename, priority): + def _load_css_from_file(self, + filename: str, + priority: CSSPriority + ) -> None: path = configpaths.get('STYLE') / filename try: with open(path, "r", encoding='utf8') as file_: @@ -156,7 +165,7 @@ def _load_css_from_file(self, filename, priority): return self._activate_css(css, priority) - def _activate_css(self, css, priority): + def _activate_css(self, css: str, priority: CSSPriority) -> None: try: provider = Gtk.CssProvider() provider.load_from_data(bytes(css.encode('utf-8'))) @@ -170,7 +179,7 @@ def _activate_css(self, css, priority): log.exception('Error loading application css') @staticmethod - def _pango_to_css_weight(number): + def _pango_to_css_weight(number: str) -> int: # Pango allows for weight values between 100 and 1000 # CSS allows only full hundred numbers like 100, 200 .. number = int(number) @@ -180,14 +189,14 @@ def _pango_to_css_weight(number): return 900 return int(math.ceil(number / 100.0)) * 100 - def _gather_available_themes(self): + def _gather_available_themes(self) -> None: files = configpaths.get('MY_THEME').iterdir() self.themes = [file.stem for file in files if file.suffix == '.css'] if 'default' in self.themes: # Ignore user created themes that are named 'default' self.themes.remove('default') - def get_theme_path(self, theme, user=True): + def get_theme_path(self, theme: str, user: bool = True) -> Path: if theme == 'default' and self.prefer_dark: theme = 'default-dark' @@ -195,7 +204,7 @@ def get_theme_path(self, theme, user=True): return configpaths.get('MY_THEME') / f'{theme}.css' return configpaths.get('STYLE') / f'{theme}.css' - def _determine_theme_path(self): + def _determine_theme_path(self) -> Path: # Gets the path of the currently active theme. # If it does not exist, it falls back to the default theme theme = app.settings.get('roster_theme') @@ -211,23 +220,23 @@ def _determine_theme_path(self): log.info('Use Theme: %s', theme) return theme_path - def _load_selected(self, new_path=None): + def _load_selected(self, new_path: Optional[Path] = None) -> None: if new_path is None: self._css_path = self._determine_theme_path() else: self._css_path = new_path self._css = css_parser.parseFile(self._css_path) - def _load_default(self): + def _load_default(self) -> None: self._default_css_path = self.get_theme_path('default', user=False) self._default_css = css_parser.parseFile(self._default_css_path) - def _load_pre(self, theme): + def _load_pre(self, theme: str) -> None: log.info('Preload theme %s', theme) self._pre_css_path = self.get_theme_path(theme) self._pre_css = css_parser.parseFile(self._pre_css_path) - def _write(self, pre): + def _write(self, pre: bool) -> None: path = self._css_path css = self._css if pre: @@ -241,10 +250,16 @@ def _write(self, pre): self._load_selected() self._activate_theme() - def set_value(self, selector, attr, value, pre=False): + def set_value(self, + selector: str, + attr: StyleAttr, + value: Union[str, Pango.FontDescription], + pre: bool = False + ) -> None: if attr == StyleAttr.FONT: # forward to set_font() for convenience - return self.set_font(selector, value, pre) + self.set_font(selector, value, pre) + return if isinstance(attr, StyleAttr): attr = attr.value @@ -261,7 +276,7 @@ def set_value(self, selector, attr, value, pre=False): if not pre: self._add_to_cache(selector, attr, value) self._write(pre) - return None + return # The rule was not found, so we add it to this theme log.info('Set %s %s %s', selector, attr, value) @@ -269,9 +284,12 @@ def set_value(self, selector, attr, value, pre=False): rule.style[attr] = value css.add(rule) self._write(pre) - return None - def set_font(self, selector, description, pre=False): + def set_font(self, + selector: str, + description: Pango.FontDescription, + pre: bool = False + ) -> None: css = self._css if pre: css = self._pre_css @@ -285,7 +303,7 @@ def set_font(self, selector, description, pre=False): selector, family, size, style, weight) rule.style['font-family'] = family rule.style['font-style'] = style - rule.style['font-size'] = '%spt' % size + rule.style['font-size'] = f'{size}pt' rule.style['font-weight'] = weight if not pre: @@ -300,19 +318,24 @@ def set_font(self, selector, description, pre=False): rule = css_parser.css.CSSStyleRule(selectorText=selector) rule.style['font-family'] = family rule.style['font-style'] = style - rule.style['font-size'] = '%spt' % size + rule.style['font-size'] = f'{size}pt' rule.style['font-weight'] = weight css.add(rule) self._write(pre) - def _get_attr_from_description(self, description): + def _get_attr_from_description(self, + description: Pango.FontDescription + ) -> Tuple[Optional[str], int, str, int]: size = description.get_size() / Pango.SCALE style = self._get_string_from_pango_style(description.get_style()) - weight = self._pango_to_css_weight(int(description.get_weight())) + weight = self._pango_to_css_weight(description.get_weight()) family = description.get_family() return family, size, style, weight - def _get_default_rule(self, selector, _attr): + def _get_default_rule(self, + selector: str, + _attr: StyleAttr + ) -> Optional[css_parser.css.CSSStyleRule]: for rule in self._default_css: if rule.type != rule.STYLE_RULE: continue @@ -321,7 +344,10 @@ def _get_default_rule(self, selector, _attr): return rule return None - def get_font(self, selector, pre=False): + def get_font(self, + selector: str, + pre: bool = False + ) -> Optional[Pango.FontDescription]: if pre: css = self._pre_css else: @@ -353,7 +379,12 @@ def get_font(self, selector, pre=False): self._add_to_cache(selector, 'fontdescription', None) return None - def _get_description_from_css(self, family, size, style, weight): + def _get_description_from_css(self, + family: Optional[str], + size: Optional[str], + style: Optional[str], + weight: Optional[str] + ) -> Optional[Pango.FontDescription]: if family is None: return None desc = Pango.FontDescription() @@ -367,7 +398,7 @@ def _get_description_from_css(self, family, size, style, weight): return desc @staticmethod - def _get_pango_style_from_string(style: str) -> int: + def _get_pango_style_from_string(style: str) -> Pango.Style: if style == 'normal': return Pango.Style(0) if style == 'oblique': @@ -384,7 +415,11 @@ def _get_string_from_pango_style(style: Pango.Style) -> str: # Pango.Style.OBLIQUE: return 'oblique' - def get_value(self, selector, attr, pre=False): + def get_value(self, + selector: str, + attr: StyleAttr, + pre: bool = False + ) -> Union[str, Pango.FontDescription, None]: if attr == StyleAttr.FONT: # forward to get_font() for convenience return self.get_font(selector, pre) @@ -422,10 +457,15 @@ def get_value(self, selector, attr, pre=False): return value return None - def remove_value(self, selector, attr, pre=False): + def remove_value(self, + selector: str, + attr: StyleAttr, + pre: bool = False + ) -> None: if attr == StyleAttr.FONT: # forward to remove_font() for convenience - return self.remove_font(selector, pre) + self.remove_font(selector, pre) + return if isinstance(attr, StyleAttr): attr = attr.value @@ -441,9 +481,8 @@ def remove_value(self, selector, attr, pre=False): rule.style.removeProperty(attr) break self._write(pre) - return None - def remove_font(self, selector, pre=False): + def remove_font(self, selector: str, pre: bool = False) -> None: css = self._css if pre: css = self._pre_css @@ -460,7 +499,7 @@ def remove_font(self, selector, pre=False): break self._write(pre) - def change_theme(self, theme): + def change_theme(self, theme: str) -> bool: user = not theme == 'default' theme_path = self.get_theme_path(theme, user=user) if not theme_path.exists(): @@ -472,7 +511,7 @@ def change_theme(self, theme): log.info('Change Theme: Successful switched to %s', theme) return True - def change_preload_theme(self, theme): + def change_preload_theme(self, theme: str) -> bool: theme_path = self.get_theme_path(theme) if not theme_path.exists(): log.error('Change Preload Theme: Theme %s does not exist', @@ -482,7 +521,7 @@ def change_preload_theme(self, theme): log.info('Successful switched to %s', theme) return True - def rename_theme(self, old_theme, new_theme): + def rename_theme(self, old_theme: str, new_theme: str) -> bool: if old_theme not in self.themes: log.error('Rename Theme: Old theme %s not found', old_theme) return False @@ -501,12 +540,12 @@ def rename_theme(self, old_theme, new_theme): old_theme, new_theme) return True - def _activate_theme(self): + def _activate_theme(self) -> None: log.info('Activate theme') self._invalidate_cache() self._provider.load_from_data(self._css.cssText) - def add_new_theme(self, theme): + def add_new_theme(self, theme: str) -> bool: theme_path = self.get_theme_path(theme) if theme_path.exists(): log.error('Add Theme: %s exists already', theme_path) @@ -517,32 +556,39 @@ def add_new_theme(self, theme): log.info('Add Theme: Successful added theme %s', theme) return True - def remove_theme(self, theme): + def remove_theme(self, theme: str) -> None: theme_path = self.get_theme_path(theme) if theme_path.exists(): theme_path.unlink() self.themes.remove(theme) log.info('Remove Theme: Successful removed theme %s', theme) - def _add_to_cache(self, selector, attr, value): + def _add_to_cache(self, + selector: str, + attr: StyleAttr, + value: Union[str, Pango.FontDescription, None] + ) -> None: self._cache[selector + attr] = value - def _get_from_cache(self, selector, attr): + def _get_from_cache(self, + selector: str, + attr: StyleAttr + ) -> Union[str, Pango.FontDescription, None]: return self._cache[selector + attr] - def _invalidate_cache(self): + def _invalidate_cache(self) -> None: self._cache = {} - def refresh(self): + def refresh(self) -> None: css = '' accounts = app.settings.get_accounts() for index, account in enumerate(accounts): color = app.settings.get_account_setting(account, 'account_color') - css_class = 'gajim_class_%s' % index + css_class = f'gajim_class_{index}' css += '.%s { background-color: %s }\n' % (css_class, color) self._dynamic_dict[account] = css_class self._dynamic_provider.load_from_data(css.encode()) - def get_dynamic_class(self, name): + def get_dynamic_class(self, name: str) -> str: return self._dynamic_dict[name] ===================================== gajim/gtk/themes.py ===================================== @@ -14,11 +14,16 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <
http://www.gnu.org/licenses/
>. -from collections import namedtuple +from __future__ import annotations +from typing import NamedTuple +from typing import Any +from typing import Union + from enum import IntEnum from gi.repository import Gtk from gi.repository import Gdk +from gi.repository import Pango from gajim.common import app from gajim.common.nec import NetworkEvent @@ -31,9 +36,14 @@ from .builder import get_builder from .util import get_app_window -StyleOption = namedtuple('StyleOption', 'label selector attr') -CSS_STYLE_OPTIONS = [ +class StyleOption(NamedTuple): + label: str + selector: str + attr: StyleAttr + + +CSS_STYLE_OPTIONS: list[StyleOption] = [ StyleOption(_('Conversation: Text Font'), '.gajim-conversation-text', StyleAttr.FONT), @@ -129,7 +139,7 @@ class Column(IntEnum): class Themes(Gtk.ApplicationWindow): - def __init__(self, transient): + def __init__(self, transient: Gtk.Window) -> None: Gtk.ApplicationWindow.__init__(self) self.set_application(app.app) self.set_title(_('Gajim Themes')) @@ -154,11 +164,14 @@ def __init__(self, transient): self._fill_choose_listbox() - def _on_key_press(self, _widget, event): + def _on_key_press(self, + _widget: Gtk.Widget, + event: Gdk.EventKey + ) -> None: if event.keyval == Gdk.KEY_Escape: self.destroy() - def _get_themes(self): + def _get_themes(self) -> None: current_theme = app.settings.get('roster_theme') for theme in app.css_config.themes: if theme == current_theme: @@ -166,7 +179,10 @@ def _get_themes(self): continue self._ui.theme_store.append([theme]) - def _on_theme_name_edit(self, _renderer, path, new_name): + def _on_theme_name_edit(self, + _renderer: Gtk.CellRendererText, + path: str, + new_name: str) -> None: iter_ = self._ui.theme_store.get_iter(path) old_name = self._ui.theme_store[iter_][Column.THEME] @@ -194,10 +210,10 @@ def _on_theme_name_edit(self, _renderer, path, new_name): app.settings.set('roster_theme', new_name) self._ui.theme_store.set_value(iter_, Column.THEME, new_name) - def _select_theme_row(self, iter_): + def _select_theme_row(self, iter_: Gtk.TreeIter) -> None: self._ui.theme_treeview.get_selection().select_iter(iter_) - def _on_theme_selected(self, tree_selection): + def _on_theme_selected(self, tree_selection: Gtk.TreeSelection) -> None: store, iter_ = tree_selection.get_selected() if iter_ is None: self._clear_options() @@ -210,7 +226,7 @@ def _on_theme_selected(self, tree_selection): self._apply_theme(theme) app.nec.push_incoming_event(NetworkEvent('style-changed')) - def _load_options(self): + def _load_options(self) -> None: self._ui.option_listbox.foreach(self._remove_option) for option in CSS_STYLE_OPTIONS: value = app.css_config.get_value( @@ -222,7 +238,7 @@ def _load_options(self): row = Option(option, value) self._ui.option_listbox.add(row) - def _add_option(self, _listbox, row): + def _add_option(self, _listbox: Gtk.ListBox, row: Gtk.ListBoxRow) -> None: # Add theme if there is none store, _ = self._ui.theme_treeview.get_selection().get_selected() first = store.get_iter_first() @@ -242,18 +258,18 @@ def _add_option(self, _listbox, row): self._ui.option_listbox.add(row) self._ui.option_popover.popdown() - def _clear_options(self): + def _clear_options(self) -> None: self._ui.option_listbox.foreach(self._remove_option) - def _fill_choose_listbox(self): + def _fill_choose_listbox(self) -> None: for option in CSS_STYLE_OPTIONS: self._ui.choose_option_listbox.add(ChooseOption(option)) - def _remove_option(self, row): + def _remove_option(self, row: Gtk.ListBoxRow) -> None: self._ui.option_listbox.remove(row) row.destroy() - def _on_add_new_theme(self, *args): + def _on_add_new_theme(self, *args: Any) -> None: name = self._create_theme_name() if not app.css_config.add_new_theme(name): return @@ -265,7 +281,7 @@ def _on_add_new_theme(self, *args): self._select_theme_row(iter_) self._apply_theme(name) - def reload_roster_theme(self): + def reload_roster_theme(self) -> None: tree_selection = self._ui.theme_treeview.get_selection() store, iter_ = tree_selection.get_selected() if iter_ is None: @@ -274,25 +290,25 @@ def reload_roster_theme(self): self._apply_theme(theme) @staticmethod - def _apply_theme(theme): + def _apply_theme(theme: str) -> None: app.settings.set('roster_theme', theme) app.css_config.change_theme(theme) app.nec.push_incoming_event(NetworkEvent('theme-update')) @staticmethod - def _update_preferences_window(): + def _update_preferences_window() -> None: window = get_app_window('Preferences') if window is not None: window.update_theme_list() @staticmethod - def _create_theme_name(): - i = 0 - while 'newtheme%s' % i in app.css_config.themes: - i += 1 - return 'newtheme%s' % i + def _create_theme_name() -> str: + index = 0 + while f'newtheme{index}' in app.css_config.themes: + index += 1 + return f'newtheme{index}' - def _on_remove_theme(self, *args): + def _on_remove_theme(self, *args: Any) -> None: store, iter_ = self._ui.theme_treeview.get_selection().get_selected() if iter_ is None: return @@ -329,7 +345,10 @@ def _remove_theme(): class Option(Gtk.ListBoxRow): - def __init__(self, option, value): + def __init__(self, + option: StyleOption, + value: Union[str, Pango.FontDescription, None] + ) -> None: Gtk.ListBoxRow.__init__(self) self.option = option self._box = Gtk.Box(spacing=12) @@ -355,7 +374,7 @@ def __init__(self, option, value): self.add(self._box) self.show_all() - def _init_color(self, color): + def _init_color(self, color: str) -> None: color_button = Gtk.ColorButton() if color is not None: rgba = Gdk.RGBA() @@ -365,7 +384,7 @@ def _init_color(self, color): color_button.connect('color-set', self._on_color_set) self._box.add(color_button) - def _init_font(self, desc): + def _init_font(self, desc: Pango.FontDescription) -> None: font_button = Gtk.FontButton() if desc is not None: font_button.set_font_desc(desc) @@ -373,7 +392,7 @@ def _init_font(self, desc): font_button.connect('font-set', self._on_font_set) self._box.add(font_button) - def _on_color_set(self, color_button): + def _on_color_set(self, color_button: Gtk.ColorButton) -> None: color = color_button.get_rgba() color_string = color.to_string() app.css_config.set_value( @@ -381,13 +400,13 @@ def _on_color_set(self, color_button): app.nec.push_incoming_event(NetworkEvent('style-changed')) self.get_toplevel().reload_roster_theme() - def _on_font_set(self, font_button): + def _on_font_set(self, font_button: Gtk.FontButton) -> None: desc = font_button.get_font_desc() app.css_config.set_font(self.option.selector, desc, pre=True) app.nec.push_incoming_event(NetworkEvent('style-changed')) self.get_toplevel().reload_roster_theme() - def _on_remove(self, *args): + def _on_remove(self, *args: Any) -> None: self.get_parent().remove(self) app.css_config.remove_value( self.option.selector, self.option.attr, pre=True) @@ -401,7 +420,7 @@ def __eq__(self, other): class ChooseOption(Gtk.ListBoxRow): - def __init__(self, option): + def __init__(self, option: StyleOption) -> None: Gtk.ListBoxRow.__init__(self) self.option = option label = Gtk.Label(label=option.label) View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/84474aae9c1320d0880396261bbb79b…
-- View it on GitLab:
https://dev.gajim.org/gajim/gajim/-/compare/84474aae9c1320d0880396261bbb79b…
You're receiving this email because of your account on
dev.gajim.org
.
1
0
0
0
← Newer
1
...
4
5
6
7
8
9
10
...
20
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Results per page:
10
25
50
100
200