Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: e726baf5 by wurstsalat at 2022-12-09T23:06:57+01:00 cq: Assistant: Add overloads for add_default_page
- - - - - d409b47b by wurstsalat at 2022-12-09T23:34:18+01:00 cq: Assistant: Add overloads for get_page
- - - - - 60cf91b8 by wurstsalat at 2022-12-09T23:36:17+01:00 cq: GUI tests: Code formatting and simplifications
- - - - -
16 changed files:
- gajim/gtk/add_contact.py - gajim/gtk/assistant.py - gajim/gtk/change_password.py - gajim/gtk/component_search.py - gajim/gtk/history_export.py - gajim/gtk/history_sync.py - gajim/gtk/remove_account.py - + test/gtk/__init__.py - test/gtk/assistant.py - test/gtk/certificate_dialog.py - test/gtk/change_password.py - test/gtk/dataform.py - test/gtk/fake_dataform.py - test/gtk/groupchat_info.py - test/gtk/ssl_error_dialog.py - test/no_gui/__init__.py
Changes:
===================================== gajim/gtk/add_contact.py ===================================== @@ -40,7 +40,6 @@ from .assistant import Assistant from .assistant import Page from .assistant import ErrorPage -from .assistant import ProgressPage from .groupchat_info import GroupChatInfoScrolled from .builder import get_builder from .util import open_window @@ -76,7 +75,7 @@ def __init__(self, 'gateway': Gateway(), })
- progress = cast(ProgressPage, self.add_default_page('progress')) + progress = self.add_default_page('progress') progress.set_title(_('Gathering information…')) progress.set_text(_('Trying to gather information on this address…'))
===================================== gajim/gtk/assistant.py ===================================== @@ -16,8 +16,10 @@
from typing import Any from typing import Callable -from typing import Optional from typing import cast +from typing import Literal +from typing import Optional +from typing import overload
from gi.repository import Gdk from gi.repository import Gtk @@ -149,6 +151,15 @@ def add_pages(self, pages: dict[str, Page]): widget.connect('update-page-complete', self._update_page_complete) self._ui.stack.add_named(widget, name)
+ @overload + def add_default_page(self, name: Literal['success']) -> SuccessPage: ... + + @overload + def add_default_page(self, name: Literal['error']) -> ErrorPage: ... + + @overload + def add_default_page(self, name: Literal['progress']) -> ProgressPage: ... + def add_default_page(self, name: str) -> Page: if name == 'success': page = SuccessPage()
===================================== gajim/gtk/change_password.py ===================================== @@ -12,8 +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 cast +from typing import Literal +from typing import overload
import logging
@@ -32,7 +36,6 @@ from .assistant import Assistant from .assistant import Page from .assistant import ErrorPage -from .assistant import ProgressPage from .assistant import SuccessPage from .dataform import DataFormWidget from .util import ensure_not_destroyed @@ -58,7 +61,7 @@ def __init__(self, account: str) -> None: 'error': Error(), 'success': Success()})
- progress = cast(ProgressPage, self.add_default_page('progress')) + progress = self.add_default_page('progress') progress.set_title(_('Changing Password...')) progress.set_text(_('Trying to change password...'))
@@ -67,6 +70,21 @@ def __init__(self, account: str) -> None:
self.show_all()
+ @overload + def get_page(self, name: Literal['password']) -> EnterPassword: ... + + @overload + def get_page(self, name: Literal['next_stage']) -> NextStage: ... + + @overload + def get_page(self, name: Literal['error']) -> Error: ... + + @overload + def get_page(self, name: Literal['success']) -> Success: ... + + def get_page(self, name: str) -> Page: + return self._pages[name] + def _on_button_clicked(self, _assistant: Assistant, button_name: str @@ -84,13 +102,11 @@ def _on_button_clicked(self,
def _on_apply(self, next_stage: bool = False) -> None: if next_stage: - next_stage_page = cast(NextStage, self.get_page('next_stage')) - form = next_stage_page.get_submit_form() + form = self.get_page('next_stage').get_submit_form() self._client.get_module('Register').change_password_with_form( form, callback=self._on_change_password) else: - password_page = cast(EnterPassword, self.get_page('password')) - password = password_page.get_password() + password = self.get_page('password').get_password() self._client.get_module('Register').change_password( password, callback=self._on_change_password)
@@ -99,20 +115,17 @@ def _on_change_password(self, task: Task) -> None: try: task.finish() except ChangePasswordStanzaError as error: - next_stage_page = cast(NextStage, self.get_page('next_stage')) form = cast(SimpleDataForm, error.get_form()) - next_stage_page.set_form(form) + self.get_page('next_stage').set_form(form) self.show_page('next_stage', Gtk.StackTransitionType.SLIDE_LEFT)
except StanzaError as error: error_text = to_user_string(error) - error_page = cast(Error, self.get_page('error')) - error_page.set_text(error_text) + self.get_page('error').set_text(error_text) self.show_page('error', Gtk.StackTransitionType.SLIDE_LEFT)
else: - password_page = cast(EnterPassword, self.get_page('password')) - password = password_page.get_password() + password = self.get_page('password').get_password() passwords.save_password(self.account, password) self.show_page('success')
===================================== gajim/gtk/component_search.py ===================================== @@ -14,9 +14,13 @@ # 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 cast from typing import Any +from typing import Literal from typing import Optional +from typing import overload from typing import Union
import logging @@ -75,7 +79,7 @@ def __init__(self, 'error': Error() })
- progress = cast(ProgressPage, self.add_default_page('progress')) + progress = self.add_default_page('progress') progress.set_title(_('Searching')) progress.set_text(_('Searching…'))
@@ -91,13 +95,28 @@ def __init__(self,
self.show_all()
+ @overload + def get_page(self, name: Literal['prepare']) -> RequestForm: ... + + @overload + def get_page(self, name: Literal['form']) -> SearchForm: ... + + @overload + def get_page(self, name: Literal['result']) -> Result: ... + + @overload + def get_page(self, name: Literal['error']) -> Error: ... + + def get_page(self, name: str) -> Page: + return self._pages[name] + def _on_button_clicked(self, _assistant: Assistant, button_name: str ) -> None: if button_name == 'search': self.show_page('progress', Gtk.StackTransitionType.SLIDE_LEFT) - form = cast(SearchForm, self.get_page('form')).get_submit_form() + form = self.get_page('form').get_submit_form() self._client.get_module('Search').send_search_form( self._jid, form, True) return @@ -112,13 +131,12 @@ def _on_button_clicked(self, @ensure_not_destroyed def _search_form_received(self, event: SearchFormReceivedEvent) -> None: if not event.is_dataform: - error_page = cast(Error, self.get_page('error')) - error_page.set_text(_('Error while retrieving search form.')) + self.get_page('error').set_text( + _('Error while retrieving search form.')) self.show_page('error') return
- form_page = cast(SearchForm, self.get_page('form')) - form_page.process_search_form(event.data) + self.get_page('form').process_search_form(event.data) self.show_page('form')
@ensure_not_destroyed @@ -131,8 +149,7 @@ def _search_result_received(self, self.show_page('error') return
- result_page = cast(Result, self.get_page('result')) - result_page.process_result(event.data) + self.get_page('result').process_result(event.data) self.show_page('result')
def _on_destroy(self, *args: Any) -> None:
===================================== gajim/gtk/history_export.py ===================================== @@ -15,7 +15,9 @@ from __future__ import annotations
from typing import cast +from typing import Literal from typing import Optional +from typing import overload
import logging import time @@ -33,10 +35,8 @@ from gajim.common.storage.archive import MessageExportRow
from .assistant import Assistant -from .assistant import Page from .assistant import ErrorPage -from .assistant import SuccessPage -from .assistant import ProgressPage +from .assistant import Page from .builder import get_builder
log = logging.getLogger('gajim.gui.history_export') @@ -58,16 +58,16 @@ def __init__(self, account: Optional[str] = None) -> None:
self.add_pages({'start': SelectAccountDir(account)})
- progress_page = cast(ProgressPage, self.add_default_page('progress')) + progress_page = self.add_default_page('progress') progress_page.set_title(_('Exporting History...')) progress_page.set_text(_('Exporting your messages...'))
- success_page = cast(SuccessPage, self.add_default_page('success')) + success_page = self.add_default_page('success') success_page.set_title(_('Export Finished')) success_page.set_text( _('Your messages have been exported successfully'))
- error_page = cast(ErrorPage, self.add_default_page('error')) + error_page = self.add_default_page('error') error_page.set_title(_('Error while Exporting')) error_page.set_text( _('An error occurred while exporting your messages')) @@ -75,6 +75,15 @@ def __init__(self, account: Optional[str] = None) -> None: self.connect('button-clicked', self._on_button_clicked) self.show_all()
+ @overload + def get_page(self, name: Literal['error']) -> ErrorPage: ... + + @overload + def get_page(self, name: Literal['start']) -> SelectAccountDir: ... + + def get_page(self, name: str) -> Page: + return self._pages[name] + @staticmethod def _visible_func(_assistant: Assistant, page_name: str) -> list[str]: if page_name == 'start': @@ -105,7 +114,7 @@ def _on_button_clicked(self, self.destroy()
def _on_export(self) -> None: - start_page = cast(SelectAccountDir, self.get_page('start')) + start_page = self.get_page('start') account, directory = start_page.get_account_and_directory()
current_time = datetime.now() @@ -123,8 +132,7 @@ def _on_export(self) -> None: try: file_path.mkdir(parents=True, exist_ok=True) except OSError as err: - error_page = cast(ErrorPage, self.get_page('error')) - error_page.set_text( + self.get_page('error').set_text( _('An error occurred while trying to create a ' 'file at %(path)s: %(error)s') % { 'path': file_path,
===================================== gajim/gtk/history_sync.py ===================================== @@ -15,7 +15,9 @@ from __future__ import annotations
from typing import cast +from typing import Literal from typing import Optional +from typing import overload
import logging from datetime import datetime @@ -85,7 +87,7 @@ def __init__(self, account: str) -> None: })
self.add_default_page('success') - success_page = cast(SuccessPage, self.get_page('success')) + success_page = self.get_page('success') success_page.set_title(_('Synchronize Chat History')) success_page.set_heading(_('Finished'))
@@ -108,6 +110,18 @@ def __init__(self, account: str) -> None:
self.show_all()
+ @overload + def get_page(self, name: Literal['select']) -> SelectTime: ... + + @overload + def get_page(self, name: Literal['progress']) -> Progress: ... + + @overload + def get_page(self, name: Literal['success']) -> SuccessPage: ... + + def get_page(self, name: str) -> Page: + return self._pages[name] + @staticmethod def _visible_func(_assistant: Assistant, page_name: str) -> list[str]: if page_name == 'select': @@ -134,7 +148,7 @@ def _on_button_clicked(self, self.destroy()
def _prepare_query(self) -> None: - select_time_page = cast(SelectTime, self.get_page('select')) + select_time_page = self.get_page('select') self._timedelta = select_time_page.get_timedelta() if self._timedelta is not None: self._start = self._now - self._timedelta @@ -159,8 +173,7 @@ def _received_count(self, task: Task) -> None: return
if result.rsm.count is not None: - progress_page = cast(Progress, self.get_page('progress')) - progress_page.set_count(int(result.rsm.count)) + self.get_page('progress').set_count(int(result.rsm.count)) mam_module = self._client.get_module('MAM') self._query_id = mam_module.request_archive_interval( self._start, self._end) @@ -171,10 +184,10 @@ def _received_finished(self, event: ArchivingIntervalFinished) -> None: return self._query_id = None log.info('Query finished') - progress_page = cast(Progress, self.get_page('progress')) + progress_page = self.get_page('progress') GLib.idle_add(progress_page.set_finished) received_count = progress_page.get_received_count() - success_page = cast(SuccessPage, self.get_page('success')) + success_page = self.get_page('success') success_page.set_text(_('Finished synchronising chat history:\n' '%s messages downloaded') % received_count) self.show_page('success') @@ -185,7 +198,7 @@ def _mam_message_received(self, event: RawMamMessageReceived) -> None: return
log.debug('Received message') - progress_page = cast(Progress, self.get_page('progress')) + progress_page = self.get_page('progress') GLib.idle_add(progress_page.set_fraction)
===================================== gajim/gtk/remove_account.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 + from typing import Any -from typing import cast +from typing import Literal +from typing import overload
import logging
@@ -32,7 +35,6 @@
from .assistant import Assistant from .assistant import Page -from .assistant import ProgressPage from .assistant import ErrorPage from .assistant import SuccessPage
@@ -61,7 +63,7 @@ def __init__(self, account: str) -> None: 'error': Error(), 'success': Success()})
- progress = cast(ProgressPage, self.add_default_page('progress')) + progress = self.add_default_page('progress') progress.set_title(_('Removing Account...')) progress.set_text(_('Trying to remove account...'))
@@ -78,6 +80,18 @@ def __init__(self, account: str) -> None:
self.show_all()
+ @overload + def get_page(self, name: Literal['remove_choice']) -> RemoveChoice: ... + + @overload + def get_page(self, name: Literal['error']) -> Error: ... + + @overload + def get_page(self, name: Literal['success']) -> Success: ... + + def get_page(self, name: str) -> Page: + return self._pages[name] + @event_filter(['account']) def _on_account_connected(self, _event: AccountConnected) -> None: self._client = app.get_client(self.account) @@ -93,8 +107,7 @@ def _on_account_disconnected(self, _event: AccountDisconnected) -> None:
def _set_remove_from_server_checkbox(self) -> None: enabled = self._client is not None and self._client.state.is_available - remove_choice_page = cast(RemoveChoice, self.get_page('remove_choice')) - remove_choice_page.set_remove_from_server(enabled) + self.get_page('remove_choice').set_remove_from_server(enabled)
def _on_button_clicked(self, _assistant: Assistant, @@ -117,7 +130,7 @@ def _on_button_clicked(self, self.destroy()
def _on_remove(self, *args: Any) -> None: - remove_choice_page = cast(RemoveChoice, self.get_page('remove_choice')) + remove_choice_page = self.get_page('remove_choice') if remove_choice_page.remove_from_server: assert self._client is not None self._client.set_remove_account(True) @@ -141,8 +154,7 @@ def _on_remove_response(self, task: Task) -> None: self._client.set_remove_account(False)
error_text = to_user_string(error) - error_page = cast(Error, self.get_page('error')) - error_page.set_text(error_text) + self.get_page('error').set_text(error_text) self.show_page('error') return
===================================== test/gtk/__init__.py ===================================== @@ -0,0 +1,14 @@ +import gi + + +def require_versions(): + gi.require_versions({'Gdk': '3.0', + 'GLib': '2.0', + 'Gio': '2.0', + 'Gtk': '3.0', + 'GtkSource': '4', + 'GObject': '2.0', + 'Pango': '1.0'}) + + +require_versions()
===================================== test/gtk/assistant.py ===================================== @@ -1,5 +1,3 @@ -import gi -gi.require_version('Gtk', '3.0') from gi.repository import Gtk
from gajim.common.const import CSSPriority @@ -10,7 +8,8 @@ from gajim.gui.assistant import Assistant from gajim.gui.assistant import Page
-from test.gtk import util +from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
@@ -46,7 +45,7 @@ def __init__(self): self.show_all()
@staticmethod - def _visible_func(_assistant, page_name): + def _visible_func(_assistant: Assistant, page_name: str) -> list[str]: if page_name == 'start': return ['forward']
@@ -60,7 +59,11 @@ def _visible_func(_assistant, page_name): return ['back', 'close'] raise ValueError('page %s unknown' % page_name)
- 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 == 'forward': if page == 'start': @@ -83,7 +86,7 @@ def _on_button_clicked(self, _assistant, button_name): if button_name == 'close': self.destroy()
- def _on_page_changed(self, _assistant, page_name): + def _on_page_changed(self, _assistant: Assistant, page_name: str) -> None: if page_name == 'start': self.set_default_button('forward')
@@ -114,7 +117,8 @@ def __init__(self): label1.set_justify(Gtk.Justification.CENTER) label1.set_margin_bottom(24)
- entry = Gtk.Entry(activates_default=True) + entry = Gtk.Entry() + entry.set_activates_default(True) entry.connect('changed', self._on_changed)
self._server = Gtk.CheckButton.new_with_mnemonic('A fancy checkbox') @@ -126,7 +130,7 @@ def __init__(self): self.pack_start(self._server, False, True, 0) self.show_all()
- def _on_changed(self, entry): + def _on_changed(self, entry: Gtk.Entry) -> None: self.complete = bool(entry.get_text()) self.update_page_complete()
===================================== test/gtk/certificate_dialog.py ===================================== @@ -1,16 +1,15 @@ -import gi -gi.require_version('Gio', '2.0') -gi.require_version('Gtk', '3.0') from gi.repository import Gio from gi.repository import Gtk
+from gajim.common.const import CSSPriority + from gajim import gui gui.init('gtk')
-from test.gtk import util -from gajim.common.const import CSSPriority from gajim.gui.certificate_dialog import CertificateDialog
+from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
cert = '''
===================================== test/gtk/change_password.py ===================================== @@ -2,23 +2,21 @@
from functools import partial
-import gi -gi.require_version('Gtk', '3.0') -from gi.repository import Gtk - from nbxmpp.modules.dataforms import create_field from nbxmpp.modules.dataforms import SimpleDataForm
+from gi.repository import Gtk + +from gajim.common import app from gajim.common.const import CSSPriority
from gajim import gui gui.init('gtk')
-from gajim.common import app - from gajim.gui.change_password import ChangePassword
-from test.gtk import util +from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
app.get_client = MagicMock() @@ -32,14 +30,16 @@
form = SimpleDataForm(type_='form', fields=fields)
-def _apply(self, next_stage=False): + +def _apply(self: ChangePassword, next_stage: bool = False) -> None: if next_stage: self.get_page('next_stage').get_submit_form() else: self.get_page('next_stage').set_form(form) self.show_page('next_stage', Gtk.StackTransitionType.SLIDE_LEFT)
-win = ChangePassword(None) + +win = ChangePassword('') win._on_apply = partial(_apply, win)
win.connect('destroy', Gtk.main_quit)
===================================== test/gtk/dataform.py ===================================== @@ -2,21 +2,21 @@
from base64 import b64decode
-import gi -gi.require_version('Gtk', '3.0') +from nbxmpp.modules.dataforms import extend_form +from nbxmpp.simplexml import Node + from gi.repository import Gtk
-import nbxmpp -from nbxmpp.modules.dataforms import extend_form +from gajim.common import app +from gajim.common.const import CSSPriority
from gajim import gui gui.init('gtk')
from gajim.gui.dataform import DataFormWidget -from gajim.common.const import CSSPriority -from gajim.common import app
-from test.gtk import util +from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
image = '''iVBORw0KGgoAAAANSUhEUgAAAIwAAAA8CAAAAACRYQ2XAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiCwQXMiypK @@ -130,10 +130,11 @@ def __init__(self): 'form-width': 435, } self._widget = DataFormWidget( - extend_form(node=nbxmpp.Node(node=FORM)), options) + extend_form(node=Node(node=FORM)), options) self.add(self._widget) self.show()
+ win = DataFormWindow() win.connect('destroy', Gtk.main_quit) win.show_all()
===================================== test/gtk/fake_dataform.py ===================================== @@ -1,5 +1,3 @@ -import gi -gi.require_version('Gtk', '3.0') from gi.repository import Gtk
from gajim import gui @@ -9,7 +7,8 @@
from gajim.gui.dataform import FakeDataFormWidget
-from test.gtk import util +from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
@@ -40,6 +39,7 @@ 'redirect-url': 'https://jabber.at/account/register/' }
+ class DataFormWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title='Data Form Test') @@ -48,6 +48,7 @@ def __init__(self): self.add(self._widget) self.show()
+ win = DataFormWindow() win.connect('destroy', Gtk.main_quit) win.show_all()
===================================== test/gtk/groupchat_info.py ===================================== @@ -1,22 +1,21 @@ from unittest.mock import MagicMock
-import gi -gi.require_version('Gtk', '3.0') -from gi.repository import Gtk - from nbxmpp.protocol import Iq from nbxmpp.modules.discovery import parse_disco_info from nbxmpp.structs import MucSubject
+from gi.repository import Gtk + from gajim.common import app from gajim.common.const import CSSPriority
from gajim import gui gui.init('gtk')
-from test.gtk import util from gajim.gui.groupchat_info import GroupChatInfoScrolled
+from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
stanza = Iq(node=''' @@ -97,6 +96,7 @@ app.css_config = MagicMock() app.css_config.get_value = MagicMock(return_value='rgb(100, 100, 255)')
+ class GroupchatInfo(Gtk.ApplicationWindow): def __init__(self): Gtk.ApplicationWindow.__init__(self)
===================================== test/gtk/ssl_error_dialog.py ===================================== @@ -1,20 +1,17 @@ from unittest.mock import MagicMock
-import gi -gi.require_version('Gio', '2.0') -gi.require_version('Gtk', '3.0') from gi.repository import Gio from gi.repository import Gtk
from gajim import gui gui.init('gtk') - -from test.gtk import util - from gajim.common import app from gajim.common.const import CSSPriority + from gajim.gui.ssl_error_dialog import SSLErrorDialog
+from . import util + util.load_style('gajim.css', CSSPriority.APPLICATION)
cert = '''
===================================== test/no_gui/__init__.py ===================================== @@ -1,5 +1,6 @@ import gi
+ def require_versions(): gi.require_versions({'Gdk': '3.0', 'GLib': '2.0', @@ -9,4 +10,5 @@ def require_versions(): 'GObject': '2.0', 'Pango': '1.0'})
+ require_versions()
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/83f2386574ca78f586b4544ca269bf06...