From 3e7d733294d23e2b836ed3540ef505b79d24d10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sat, 24 Oct 2026 09:58:10 -0700 Subject: [PATCH] UserSettingsView: merge avatar popover --- po/POTFILES | 1 - src/Misc/UserUtils.vala | 34 ++++++ src/Views/UserSettingsView.vala | 73 ++++++++++++- src/Widgets/Popovers/AvatarPopover.vala | 131 ------------------------ src/meson.build | 1 - 5 files changed, 106 insertions(+), 134 deletions(-) delete mode 100644 src/Widgets/Popovers/AvatarPopover.vala diff --git a/po/POTFILES b/po/POTFILES index 1c9efe52..dfa26b97 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -8,7 +8,6 @@ src/Misc/Utils.vala src/Views/GuestSettingsView.vala src/Views/MainView.vala src/Views/UserSettingsView.vala -src/Widgets/Popovers/AvatarPopover.vala src/Widgets/CropView.vala src/Widgets/ErrorRevealer.vala src/Widgets/PasswordEditor.vala diff --git a/src/Misc/UserUtils.vala b/src/Misc/UserUtils.vala index 95faddb9..53921a32 100644 --- a/src/Misc/UserUtils.vala +++ b/src/Misc/UserUtils.vala @@ -78,5 +78,39 @@ namespace SwitchboardPlugUserAccounts { } } } + + public void change_avatar (Gdk.Pixbuf? new_pixbuf) { + if (get_current_user () != user) { + var permission = get_permission (); + if (!permission.allowed) { + try { + permission.acquire (); + } catch (Error e) { + critical (e.message); + return; + } + } + } + + if (new_pixbuf != null) { + var path = Path.build_filename (Environment.get_tmp_dir (), "user-icon-0"); + int i = 0; + while (FileUtils.test (path, FileTest.EXISTS)) { + path = Path.build_filename (Environment.get_tmp_dir (), "user-icon-%d".printf (i)); + i++; + } + try { + debug ("Saving temporary avatar file to %s".printf (path)); + new_pixbuf.savev (path, "png", {}, {}); + debug ("Setting avatar icon file for %s from temporary file %s".printf (user.get_user_name (), path)); + user.set_icon_file (path); + } catch (Error e) { + critical (e.message); + } + } else { + debug ("Setting no avatar icon file for %s".printf (user.get_user_name ())); + user.set_icon_file (""); + } + } } } diff --git a/src/Views/UserSettingsView.vala b/src/Views/UserSettingsView.vala index a8e3755e..197fcab8 100644 --- a/src/Views/UserSettingsView.vala +++ b/src/Views/UserSettingsView.vala @@ -45,6 +45,7 @@ namespace SwitchboardPlugUserAccounts.Widgets { private Gtk.Switch autologin_switch; private Gtk.Switch lock_switch; private Gtk.InfoBar infobar; + private Gtk.Popover avatar_popover; //lock widgets private Gtk.Image full_name_lock; @@ -88,7 +89,29 @@ namespace SwitchboardPlugUserAccounts.Widgets { avatar = new Adw.Avatar (48, user.real_name, true); - var avatar_popover = new AvatarPopover (user, utils); + var remove_button = new Gtk.Button () { + child = new Gtk.Label (_("Remove")) { + xalign = 0 + } + }; + remove_button.add_css_class (Granite.STYLE_CLASS_MENUITEM); + remove_button.add_css_class (Granite.STYLE_CLASS_DESTRUCTIVE_ACTION); + + var select_button = new Gtk.Button () { + child = new Gtk.Label (_("Set from File…")) { + xalign = 0 + } + }; + select_button.add_css_class (Granite.STYLE_CLASS_MENUITEM); + + var button_box = new Gtk.Box (VERTICAL, 0); + button_box.append (remove_button); + button_box.append (select_button); + + avatar_popover = new Gtk.Popover () { + autohide = true, + child = button_box + }; avatar_popover.add_css_class (Granite.STYLE_CLASS_MENU); var avatar_button = new Gtk.MenuButton () { @@ -423,6 +446,27 @@ namespace SwitchboardPlugUserAccounts.Widgets { user.changed.connect (update_ui); user.changed.connect (update_permission); + + avatar_button.activate.connect (() => { + if (!avatar_button.active) { + return; + } + + select_button.grab_focus (); + + if (user.get_icon_file ().contains (".face")) { + remove_button.sensitive = false; + } else { + remove_button.sensitive = true; + } + }); + + remove_button.clicked.connect (() => { + avatar_popover.popdown (); + utils.change_avatar (null); + }); + + select_button.clicked.connect (select_from_file); } private void update_permission () { @@ -701,5 +745,32 @@ namespace SwitchboardPlugUserAccounts.Widgets { } } } + + private async void select_from_file () { + avatar_popover.popdown (); + + var filter = new Gtk.FileFilter (); + filter.set_filter_name (_("Images")); + filter.add_mime_type ("image/jpeg"); + filter.add_mime_type ("image/jpg"); + filter.add_mime_type ("image/png"); + + var file_dialog = new Gtk.FileDialog () { + title = _("Select an image"), + accept_label = _("Open") + }; + file_dialog.default_filter = filter; + + try { + File file = yield file_dialog.open (((Gtk.Application) Application.get_default ()).active_window, null); + var path = file.get_path (); + + var avatar_dialog = new Dialogs.AvatarDialog (path); + avatar_dialog.request_avatar_change.connect (utils.change_avatar); + avatar_dialog.present (); + } catch (Error err) { + warning ("Failed to select image: %s", err.message); + } + } } } diff --git a/src/Widgets/Popovers/AvatarPopover.vala b/src/Widgets/Popovers/AvatarPopover.vala deleted file mode 100644 index 053666ef..00000000 --- a/src/Widgets/Popovers/AvatarPopover.vala +++ /dev/null @@ -1,131 +0,0 @@ -/* -* Copyright 2014-2020 elementary, Inc. (https://elementary.io) -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -*/ - -public class SwitchboardPlugUserAccounts.Widgets.AvatarPopover : Gtk.Popover { - public Act.User user { get; construct; } - public UserUtils utils { get; construct; } - - public AvatarPopover (Act.User user, UserUtils utils) { - Object ( - user: user, - utils: utils - ); - } - - construct { - var remove_button_label = new Gtk.Label (_("Remove")) { - xalign = 0 - }; - - var remove_button = new Gtk.Button () { - child = remove_button_label - }; - remove_button.add_css_class (Granite.STYLE_CLASS_MENUITEM); - remove_button.add_css_class (Granite.STYLE_CLASS_DESTRUCTIVE_ACTION); - - var select_button = new Gtk.Button () { - child = new Gtk.Label (_("Set from File…")) { - xalign = 0 - } - }; - select_button.add_css_class (Granite.STYLE_CLASS_MENUITEM); - select_button.grab_focus (); - - var button_box = new Gtk.Box (VERTICAL, 0); - button_box.append (remove_button); - button_box.append (select_button); - - autohide = true; - child = button_box; - - if (user.get_icon_file ().contains (".face")) { - remove_button.sensitive = false; - } else { - remove_button.sensitive = true; - } - - remove_button.clicked.connect (() => { - popdown (); - change_avatar (null); - }); - - select_button.clicked.connect (select_from_file); - } - - private async void select_from_file () { - popdown (); - - var filter = new Gtk.FileFilter (); - filter.set_filter_name (_("Images")); - filter.add_mime_type ("image/jpeg"); - filter.add_mime_type ("image/jpg"); - filter.add_mime_type ("image/png"); - - var file_dialog = new Gtk.FileDialog () { - title = _("Select an image"), - accept_label = _("Open") - }; - file_dialog.default_filter = filter; - - try { - File file = yield file_dialog.open (((Gtk.Application) Application.get_default ()).active_window, null); - var path = file.get_path (); - - var avatar_dialog = new Dialogs.AvatarDialog (path); - avatar_dialog.request_avatar_change.connect (change_avatar); - avatar_dialog.present (); - } catch (Error err) { - warning ("Failed to select image: %s", err.message); - } - } - - private void change_avatar (Gdk.Pixbuf? new_pixbuf) { - if (get_current_user () != user) { - var permission = get_permission (); - if (!permission.allowed) { - try { - permission.acquire (); - } catch (Error e) { - critical (e.message); - return; - } - } - } - - if (new_pixbuf != null) { - var path = Path.build_filename (Environment.get_tmp_dir (), "user-icon-0"); - int i = 0; - while (FileUtils.test (path, FileTest.EXISTS)) { - path = Path.build_filename (Environment.get_tmp_dir (), "user-icon-%d".printf (i)); - i++; - } - try { - debug ("Saving temporary avatar file to %s".printf (path)); - new_pixbuf.savev (path, "png", {}, {}); - debug ("Setting avatar icon file for %s from temporary file %s".printf (user.get_user_name (), path)); - user.set_icon_file (path); - } catch (Error e) { - critical (e.message); - } - } else { - debug ("Setting no avatar icon file for %s".printf (user.get_user_name ())); - user.set_icon_file (""); - } - } -} diff --git a/src/meson.build b/src/meson.build index 4e14ad79..2bb52d8d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,7 +15,6 @@ plug_files = files( 'Views/GuestSettingsView.vala', 'Views/MainView.vala', 'Views/UserSettingsView.vala', - 'Widgets/Popovers/AvatarPopover.vala', 'Widgets/CropView.vala', 'Widgets/ErrorRevealer.vala', 'Widgets/PasswordEditor.vala',