diff --git a/gajim/data/gui/app_page.ui b/gajim/data/gui/app_page.ui index 4abd0f6cba420d8b7034fb958d0fa8a1ac526b4d..e012dae496101955d97b036d1321815bd3966fde 100644 --- a/gajim/data/gui/app_page.ui +++ b/gajim/data/gui/app_page.ui @@ -13,7 +13,7 @@ <property name="receives-default">True</property> <property name="tooltip-text" translatable="yes">Dismiss</property> <property name="valign">center</property> - <signal name="clicked" handler="_on_dismiss_update_clicked" swapped="no"/> + <signal name="clicked" handler="_on_dismiss_clicked" swapped="no"/> <child> <object class="GtkImage"> <property name="visible">True</property> @@ -31,7 +31,7 @@ </child> <child> <object class="GtkButton"> - <property name="label" translatable="yes">Website</property> + <property name="label" translatable="yes">Download</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">True</property> @@ -54,6 +54,7 @@ <property name="can-focus">False</property> <property name="valign">center</property> <property name="orientation">vertical</property> + <property name="spacing">3</property> <child> <object class="GtkLabel"> <property name="visible">True</property> @@ -79,7 +80,7 @@ <property name="can-focus">False</property> <property name="halign">start</property> <property name="ellipsize">end</property> - <property name="max-width-chars">30</property> + <property name="max-width-chars">40</property> <property name="xalign">0</property> <style> <class name="dim-label"/> @@ -99,7 +100,7 @@ </packing> </child> <style> - <class name="padding-6"/> + <class name="padding-12"/> </style> </object> <object class="GtkBox" id="gajim_update_check"> @@ -131,12 +132,12 @@ </child> <child> <object class="GtkButton"> - <property name="label" translatable="yes">Yes</property> + <property name="label" translatable="yes">Activate</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">True</property> <property name="valign">center</property> - <signal name="clicked" handler="_on_check_clicked" swapped="no"/> + <signal name="clicked" handler="_on_activate_check_clicked" swapped="no"/> <style> <class name="suggested-action"/> </style> @@ -154,6 +155,7 @@ <property name="can-focus">False</property> <property name="valign">center</property> <property name="orientation">vertical</property> + <property name="spacing">3</property> <child> <object class="GtkLabel"> <property name="visible">True</property> @@ -180,8 +182,91 @@ <property name="halign">start</property> <property name="label" translatable="yes">Search for Gajim updates periodically?</property> <property name="ellipsize">end</property> + <property name="max-width-chars">40</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <style> + <class name="padding-12"/> + </style> + </object> + <object class="GtkBox" id="plugin_updates"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Dismiss</property> + <property name="valign">center</property> + <signal name="clicked" handler="_on_dismiss_clicked" swapped="no"/> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">window-close-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="valign">center</property> + <property name="orientation">vertical</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Plugin Updates</property> + <property name="ellipsize">end</property> <property name="max-width-chars">30</property> <property name="xalign">0</property> + <style> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">There are updates for Gajim’s plugins</property> + <property name="ellipsize">end</property> + <property name="max-width-chars">40</property> + <property name="xalign">0</property> <style> <class name="dim-label"/> </style> @@ -192,15 +277,168 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="auto_update_plugins"> + <property name="label" translatable="yes">Update plugins automatically</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="tooltip-text" translatable="yes">Open Plugins…</property> + <property name="valign">center</property> + <signal name="clicked" handler="_on_open_plugins" swapped="no"/> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">system-software-install-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">Update</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="valign">center</property> + <signal name="clicked" handler="_on_update_plugins_clicked" swapped="no"/> + <style> + <class name="suggested-action"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">3</property> + </packing> + </child> + <style> + <class name="padding-12"/> + </style> + </object> + <object class="GtkBox" id="plugin_updates_finished"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="valign">center</property> + <property name="orientation">vertical</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Plugins Updated Successfully</property> + <property name="ellipsize">end</property> + <property name="max-width-chars">30</property> + <property name="xalign">0</property> + <style> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Updates will be installed next time Gajim is started</property> + <property name="ellipsize">end</property> + <property name="max-width-chars">40</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="notify_after_plugin_updates"> + <property name="label" translatable="yes">Don’t show this again</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Dismiss</property> + <property name="valign">center</property> + <signal name="clicked" handler="_on_dismiss_update_notification" swapped="no"/> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">window-close-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> <property name="position">2</property> </packing> </child> <style> - <class name="padding-6"/> + <class name="padding-12"/> </style> </object> </interface> diff --git a/gajim/data/style/gajim.css b/gajim/data/style/gajim.css index 288462dc8499769dfbac811251699379110802bc..5b7bbbbbe41294dcdb4d5f5f7d23fe9f0e4d2544 100644 --- a/gajim/data/style/gajim.css +++ b/gajim/data/style/gajim.css @@ -753,6 +753,7 @@ .margin-3 { margin: 3px; } .margin-12 { margin: 12px; } .margin-18 { margin: 18px; } .padding-6 { margin: 6px; } +.padding-12 { margin: 12px; } .padding-18 { margin: 18px; } .padding-left30 { padding-left: 30px; } diff --git a/gajim/gtk/app_page.py b/gajim/gtk/app_page.py index b3c272eba2dffb8c5323cdffe160eb9fd0eb6caf..99d00a1282b272ca1e50792927530c98c3784d95 100644 --- a/gajim/gtk/app_page.py +++ b/gajim/gtk/app_page.py @@ -24,6 +24,7 @@ from gajim.common.events import ApplicationEvent from gajim.common.helpers import open_uri from gajim.common.i18n import _ +from gajim.plugins.pluginmanager import PluginManifest from .status_message_selector import StatusMessageSelector from .status_selector import StatusSelector @@ -71,9 +72,18 @@ def __init__(self) -> None: self.show_all() - def add_app_message(self, category: str, message: Optional[str]) -> None: + def add_app_message(self, + category: str, + message: Optional[str] + ) -> None: self._app_message_listbox.add_app_message(category, message) + self._unread_count += 1 + self.emit('unread-count-changed', self._unread_count) + def add_plugin_update_message(self, + manifests: list[PluginManifest] + ) -> None: + self._app_message_listbox.add_plugin_update_message(manifests) self._unread_count += 1 self.emit('unread-count-changed', self._unread_count) @@ -104,6 +114,12 @@ def add_app_message(self, category: str, message: Optional[str]) -> None: row = AppMessageRow(category, message) self.add(row) + def add_plugin_update_message(self, + manifests: list[PluginManifest] + ) -> None: + row = AppMessageRow('plugin-updates', plugin_manifests=manifests) + self.add(row) + def remove_app_message(self, row: Gtk.ListBoxRow) -> None: self.remove(row) app_page = cast(AppPage, self.get_parent()) @@ -111,8 +127,14 @@ def remove_app_message(self, row: Gtk.ListBoxRow) -> None: class AppMessageRow(Gtk.ListBoxRow): - def __init__(self, category: str, message: Optional[str] = None) -> None: + def __init__(self, + category: str, + message: Optional[str] = None, + plugin_manifests: Optional[list[PluginManifest]] = None + ) -> None: Gtk.ListBoxRow.__init__(self) + self._plugin_manifests = plugin_manifests + self._ui = get_builder('app_page.ui') if category == 'allow-gajim-update-check': @@ -123,24 +145,46 @@ def __init__(self, category: str, message: Optional[str] = None) -> None: text = _('Version %s is available') % message self._ui.update_message.set_text(text) + if category == 'plugin-updates': + self.add(self._ui.plugin_updates) + + if category == 'plugin-updates-finished': + self.add(self._ui.plugin_updates_finished) + self._ui.connect_signals(self) self.show_all() - def _on_check_clicked(self, _button: Gtk.Button) -> None: - app.app.check_for_gajim_updates() + def _remove_app_message(self) -> None: list_box = cast(AppMessageListBox, self.get_parent()) list_box.remove_app_message(self) + def _on_activate_check_clicked(self, _button: Gtk.Button) -> None: + app.app.check_for_gajim_updates() + self._remove_app_message() + def _on_dismiss_check_clicked(self, _button: Gtk.Button) -> None: app.settings.set('check_for_update', False) - list_box = cast(AppMessageListBox, self.get_parent()) - list_box.remove_app_message(self) + self._remove_app_message() def _on_visit_website_clicked(self, _button: Gtk.Button) -> None: open_uri('https://gajim.org/download') - list_box = cast(AppMessageListBox, self.get_parent()) - list_box.remove_app_message(self) - - def _on_dismiss_update_clicked(self, _button: Gtk.Button) -> None: - list_box = cast(AppMessageListBox, self.get_parent()) - list_box.remove_app_message(self) + self._remove_app_message() + + def _on_dismiss_clicked(self, _button: Gtk.Button) -> None: + self._remove_app_message() + + def _on_update_plugins_clicked(self, _button: Gtk.Button) -> None: + if self._ui.auto_update_plugins.get_active(): + app.settings.set('plugins_auto_update', True) + assert self._plugin_manifests is not None + app.plugin_repository.download_plugins(self._plugin_manifests) + self._remove_app_message() + + def _on_dismiss_update_notification(self, _button: Gtk.Button) -> None: + if self._ui.notify_after_plugin_updates.get_active(): + app.settings.set('plugins_notify_after_update', False) + self._remove_app_message() + + def _on_open_plugins(self, _button: Gtk.Button) -> None: + app.app.activate_action('plugins', None) + self._remove_app_message() diff --git a/gajim/gtk/builder.pyi b/gajim/gtk/builder.pyi index ccd7e8ee4224789887d6edef40bfa0b8e147ca98..75a71caf5288ecb7737bfb1210fc1207ed360ac7 100644 --- a/gajim/gtk/builder.pyi +++ b/gajim/gtk/builder.pyi @@ -101,6 +101,10 @@ class AppPageBuilder(Builder): gajim_update: Gtk.Box update_message: Gtk.Label gajim_update_check: Gtk.Box + plugin_updates: Gtk.Box + auto_update_plugins: Gtk.CheckButton + plugin_updates_finished: Gtk.Box + notify_after_plugin_updates: Gtk.CheckButton class ApplicationMenuBuilder(Builder): diff --git a/gajim/gtk/main.py b/gajim/gtk/main.py index 2e4c7aad62317363ab158871af4368fd32f88e5f..d5ad3f2b229c6ae86164ad8ea10629ace79c12fb 100644 --- a/gajim/gtk/main.py +++ b/gajim/gtk/main.py @@ -897,39 +897,9 @@ def _on_plugin_updates_available(self, _repository: PluginRepository, _signal_name: str, manifests: list[PluginManifest]) -> None: - - def _open_update(is_checked: bool): - if is_checked: - app.settings.set('plugins_auto_update', True) - app.plugin_repository.download_plugins(manifests) - - plugins_str = '\n' - plugins_str += '\n'.join([manifest.name for manifest in manifests]) - ConfirmationCheckDialog( - _('Plugin Updates'), - _('Plugin Updates Available'), - _('There are updates for your plugins:\n' - '<b>%s</b>') % plugins_str, - _('Update plugins automatically next time'), - [DialogButton.make('Cancel'), - DialogButton.make('Accept', - text=_('_Update'), - is_default=True, - callback=_open_update)]).show() + self._app_page.add_plugin_update_message(manifests) def _on_plugin_auto_update_finished(self, _repository: PluginRepository, _signal_name: str) -> None: - - def _on_ok(is_checked: bool) -> None: - if is_checked: - app.settings.set('plugins_notify_after_update', False) - - ConfirmationCheckDialog( - _('Plugins Updated'), - _('Plugins Updated'), - _('Plugin updates have successfully been downloaded.\n' - 'Updates will be installed next time Gajim is started.'), - _('Do not show this message again'), - [DialogButton.make('OK', - callback=_on_ok)]).show() + self.add_app_message('plugin-updates-finished')