2019-12-17 16:41:03 +01:00
|
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
|
|
|
*
|
|
|
|
|
* Copyright © 2019 Endless Mobile, Inc.
|
|
|
|
|
*
|
|
|
|
|
* 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 2 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
* Authors:
|
|
|
|
|
* - Philip Withnall <withnall@endlessm.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
#include <act/act.h>
|
2019-12-17 16:41:03 +01:00
|
|
|
|
#include <glib.h>
|
|
|
|
|
#include <glib-object.h>
|
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
|
#include <gio/gio.h>
|
|
|
|
|
#include <gtk/gtk.h>
|
2022-07-08 20:11:30 +02:00
|
|
|
|
#include <adwaita.h>
|
2020-01-30 12:43:46 +01:00
|
|
|
|
#include <libmalcontent-ui/malcontent-ui.h>
|
2020-01-28 15:30:26 +01:00
|
|
|
|
#include <polkit/polkit.h>
|
2019-12-17 16:41:03 +01:00
|
|
|
|
|
|
|
|
|
#include "application.h"
|
2020-01-10 18:03:20 +01:00
|
|
|
|
#include "user-selector.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void user_selector_notify_user_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data);
|
|
|
|
|
static void user_manager_notify_is_loaded_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data);
|
2020-01-28 15:30:26 +01:00
|
|
|
|
static void permission_new_cb (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data);
|
|
|
|
|
static void permission_notify_allowed_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data);
|
2020-01-28 16:07:18 +01:00
|
|
|
|
static void user_accounts_panel_button_clicked_cb (GtkButton *button,
|
|
|
|
|
gpointer user_data);
|
2020-03-27 23:07:34 +01:00
|
|
|
|
static void about_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
|
|
|
|
|
static void help_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
|
|
|
|
|
static void quit_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data);
|
2019-12-17 16:41:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* MctApplication:
|
|
|
|
|
*
|
|
|
|
|
* #MctApplication is a top-level object representing the parental controls
|
|
|
|
|
* application.
|
|
|
|
|
*
|
|
|
|
|
* Since: 0.5.0
|
|
|
|
|
*/
|
|
|
|
|
struct _MctApplication
|
|
|
|
|
{
|
|
|
|
|
GtkApplication parent_instance;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
GCancellable *cancellable; /* (owned) */
|
|
|
|
|
|
2020-03-23 15:43:22 +01:00
|
|
|
|
GDBusConnection *dbus_connection; /* (owned) */
|
2020-01-10 18:03:20 +01:00
|
|
|
|
ActUserManager *user_manager; /* (owned) */
|
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
GPermission *permission; /* (owned) */
|
|
|
|
|
GError *permission_error; /* (nullable) (owned) */
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
MctUserSelector *user_selector;
|
|
|
|
|
MctUserControls *user_controls;
|
|
|
|
|
GtkStack *main_stack;
|
2022-07-08 20:11:30 +02:00
|
|
|
|
AdwStatusPage *error_page;
|
2020-01-28 15:30:26 +01:00
|
|
|
|
GtkLockButton *lock_button;
|
2020-01-28 16:07:18 +01:00
|
|
|
|
GtkButton *user_accounts_panel_button;
|
2020-11-03 17:23:48 +01:00
|
|
|
|
GtkLabel *help_label;
|
2019-12-17 16:41:03 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (MctApplication, mct_application, GTK_TYPE_APPLICATION)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mct_application_init (MctApplication *self)
|
|
|
|
|
{
|
2020-01-28 15:30:26 +01:00
|
|
|
|
self->cancellable = g_cancellable_new ();
|
2019-12-17 16:41:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mct_application_constructed (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
GApplication *application = G_APPLICATION (object);
|
2020-10-19 18:55:47 +02:00
|
|
|
|
const GOptionEntry options[] =
|
|
|
|
|
{
|
|
|
|
|
{ "user", 'u', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, NULL,
|
|
|
|
|
/* Translators: This documents the --user command line option to malcontent-control: */
|
|
|
|
|
N_("User to select in the UI"),
|
|
|
|
|
/* Translators: This is a placeholder for a command line argument value: */
|
|
|
|
|
N_("USERNAME") },
|
2021-10-07 15:43:02 +02:00
|
|
|
|
{ NULL, },
|
2020-10-19 18:55:47 +02:00
|
|
|
|
};
|
2019-12-17 16:41:03 +01:00
|
|
|
|
|
|
|
|
|
g_application_set_application_id (application, "org.freedesktop.MalcontentControl");
|
|
|
|
|
|
2020-10-19 18:55:47 +02:00
|
|
|
|
g_application_add_main_option_entries (application, options);
|
|
|
|
|
g_application_set_flags (application, g_application_get_flags (application) | G_APPLICATION_HANDLES_COMMAND_LINE);
|
|
|
|
|
|
|
|
|
|
/* Translators: This is a summary of what the application does, displayed when
|
|
|
|
|
* it’s run with --help: */
|
|
|
|
|
g_application_set_option_context_parameter_string (application,
|
|
|
|
|
N_("— view and edit parental controls"));
|
|
|
|
|
|
2019-12-17 16:41:03 +01:00
|
|
|
|
/* Localisation */
|
|
|
|
|
bindtextdomain ("malcontent", PACKAGE_LOCALE_DIR);
|
|
|
|
|
bind_textdomain_codeset ("malcontent", "UTF-8");
|
|
|
|
|
textdomain ("malcontent");
|
|
|
|
|
|
|
|
|
|
g_set_application_name (_("Parental Controls"));
|
|
|
|
|
gtk_window_set_default_icon_name ("org.freedesktop.MalcontentControl");
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (mct_application_parent_class)->constructed (object);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
static void
|
|
|
|
|
mct_application_dispose (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (object);
|
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
g_cancellable_cancel (self->cancellable);
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
if (self->user_manager != NULL)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handlers_disconnect_by_func (self->user_manager,
|
|
|
|
|
user_manager_notify_is_loaded_cb, self);
|
|
|
|
|
g_clear_object (&self->user_manager);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
if (self->permission != NULL)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handlers_disconnect_by_func (self->permission,
|
|
|
|
|
permission_notify_allowed_cb, self);
|
|
|
|
|
g_clear_object (&self->permission);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-23 15:43:22 +01:00
|
|
|
|
g_clear_object (&self->dbus_connection);
|
2020-01-28 15:30:26 +01:00
|
|
|
|
g_clear_error (&self->permission_error);
|
|
|
|
|
g_clear_object (&self->cancellable);
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
G_OBJECT_CLASS (mct_application_parent_class)->dispose (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GtkWindow *
|
|
|
|
|
mct_application_get_main_window (MctApplication *self)
|
|
|
|
|
{
|
|
|
|
|
return gtk_application_get_active_window (GTK_APPLICATION (self));
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-19 14:41:17 +01:00
|
|
|
|
static void
|
|
|
|
|
mct_application_activate (GApplication *application)
|
|
|
|
|
{
|
2020-01-10 18:03:20 +01:00
|
|
|
|
MctApplication *self = MCT_APPLICATION (application);
|
2019-12-19 14:41:17 +01:00
|
|
|
|
GtkWindow *window = NULL;
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
window = mct_application_get_main_window (self);
|
2019-12-19 14:41:17 +01:00
|
|
|
|
|
|
|
|
|
if (window == NULL)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr(GtkBuilder) builder = NULL;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
g_autoptr(GError) local_error = NULL;
|
|
|
|
|
|
|
|
|
|
/* Ensure the types used in the UI are registered. */
|
|
|
|
|
g_type_ensure (MCT_TYPE_USER_CONTROLS);
|
|
|
|
|
g_type_ensure (MCT_TYPE_USER_SELECTOR);
|
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
/* Start loading the permission */
|
|
|
|
|
polkit_permission_new ("org.freedesktop.MalcontentControl.administration",
|
|
|
|
|
NULL, self->cancellable,
|
|
|
|
|
permission_new_cb, self);
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
builder = gtk_builder_new ();
|
2019-12-19 14:41:17 +01:00
|
|
|
|
|
2020-03-23 15:43:22 +01:00
|
|
|
|
g_assert (self->dbus_connection == NULL);
|
|
|
|
|
self->dbus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, self->cancellable, &local_error);
|
|
|
|
|
if (self->dbus_connection == NULL)
|
|
|
|
|
{
|
|
|
|
|
g_error ("Error getting system bus: %s", local_error->message);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
g_assert (self->user_manager == NULL);
|
|
|
|
|
self->user_manager = g_object_ref (act_user_manager_get_default ());
|
2019-12-19 14:41:17 +01:00
|
|
|
|
|
|
|
|
|
gtk_builder_set_translation_domain (builder, "malcontent");
|
2020-01-10 18:03:20 +01:00
|
|
|
|
gtk_builder_expose_object (builder, "user_manager", G_OBJECT (self->user_manager));
|
2020-03-23 15:43:22 +01:00
|
|
|
|
gtk_builder_expose_object (builder, "dbus_connection", G_OBJECT (self->dbus_connection));
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
|
|
|
|
gtk_builder_add_from_resource (builder, "/org/freedesktop/MalcontentControl/ui/main.ui", &local_error);
|
|
|
|
|
g_assert (local_error == NULL);
|
2019-12-19 14:41:17 +01:00
|
|
|
|
|
|
|
|
|
/* Set up the main window. */
|
|
|
|
|
window = GTK_WINDOW (gtk_builder_get_object (builder, "main_window"));
|
|
|
|
|
gtk_window_set_application (window, GTK_APPLICATION (application));
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
|
|
|
|
self->main_stack = GTK_STACK (gtk_builder_get_object (builder, "main_stack"));
|
|
|
|
|
self->user_selector = MCT_USER_SELECTOR (gtk_builder_get_object (builder, "user_selector"));
|
|
|
|
|
self->user_controls = MCT_USER_CONTROLS (gtk_builder_get_object (builder, "user_controls"));
|
2022-07-08 20:11:30 +02:00
|
|
|
|
self->error_page = ADW_STATUS_PAGE (gtk_builder_get_object (builder, "error_page"));
|
2020-01-28 15:30:26 +01:00
|
|
|
|
self->lock_button = GTK_LOCK_BUTTON (gtk_builder_get_object (builder, "lock_button"));
|
2020-01-28 16:07:18 +01:00
|
|
|
|
self->user_accounts_panel_button = GTK_BUTTON (gtk_builder_get_object (builder, "user_accounts_panel_button"));
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
|
|
|
|
/* Connect signals. */
|
2020-02-03 18:15:23 +01:00
|
|
|
|
g_signal_connect_object (self->user_selector, "notify::user",
|
|
|
|
|
G_CALLBACK (user_selector_notify_user_cb),
|
|
|
|
|
self, 0 /* flags */);
|
2020-01-28 16:07:18 +01:00
|
|
|
|
g_signal_connect_object (self->user_accounts_panel_button, "clicked",
|
|
|
|
|
G_CALLBACK (user_accounts_panel_button_clicked_cb),
|
|
|
|
|
self, 0 /* flags */);
|
2020-01-10 18:03:20 +01:00
|
|
|
|
g_signal_connect (self->user_manager, "notify::is-loaded",
|
|
|
|
|
G_CALLBACK (user_manager_notify_is_loaded_cb), self);
|
|
|
|
|
|
|
|
|
|
/* Work out whether to show the loading page or the main page, and show
|
|
|
|
|
* the controls for the initially selected user. */
|
|
|
|
|
user_selector_notify_user_cb (G_OBJECT (self->user_selector), NULL, self);
|
|
|
|
|
user_manager_notify_is_loaded_cb (G_OBJECT (self->user_manager), NULL, self);
|
|
|
|
|
|
2022-07-08 20:51:14 +02:00
|
|
|
|
gtk_window_present (GTK_WINDOW (window));
|
2019-12-19 14:41:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Bring the window to the front. */
|
|
|
|
|
gtk_window_present (window);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 23:07:34 +01:00
|
|
|
|
static void
|
|
|
|
|
mct_application_startup (GApplication *application)
|
|
|
|
|
{
|
|
|
|
|
const GActionEntry app_entries[] =
|
|
|
|
|
{
|
|
|
|
|
{ "about", about_action_cb, NULL, NULL, NULL, { 0, } },
|
|
|
|
|
{ "help", help_action_cb, NULL, NULL, NULL, { 0, } },
|
|
|
|
|
{ "quit", quit_action_cb, NULL, NULL, NULL, { 0, } },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Chain up. */
|
|
|
|
|
G_APPLICATION_CLASS (mct_application_parent_class)->startup (application);
|
|
|
|
|
|
2022-07-08 20:11:30 +02:00
|
|
|
|
adw_init ();
|
2021-02-08 12:27:59 +01:00
|
|
|
|
|
2020-03-27 23:07:34 +01:00
|
|
|
|
g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries,
|
|
|
|
|
G_N_ELEMENTS (app_entries), application);
|
|
|
|
|
|
|
|
|
|
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
|
|
|
|
|
"app.help", (const gchar * const[]) { "F1", NULL });
|
|
|
|
|
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
|
|
|
|
|
"app.quit", (const gchar * const[]) { "<Primary>q", "<Primary>w", NULL });
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-19 18:55:47 +02:00
|
|
|
|
static gint
|
|
|
|
|
mct_application_command_line (GApplication *application,
|
|
|
|
|
GApplicationCommandLine *command_line)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (application);
|
|
|
|
|
GVariantDict *options = g_application_command_line_get_options_dict (command_line);
|
|
|
|
|
const gchar *username;
|
|
|
|
|
|
|
|
|
|
/* Show the application. */
|
|
|
|
|
g_application_activate (application);
|
|
|
|
|
|
|
|
|
|
/* Select a user if requested. */
|
|
|
|
|
if (g_variant_dict_lookup (options, "user", "&s", &username) &&
|
|
|
|
|
!mct_user_selector_select_user_by_username (self->user_selector, username))
|
|
|
|
|
g_warning ("Failed to select user ‘%s’", username);
|
|
|
|
|
|
|
|
|
|
return 0; /* exit status */
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 16:41:03 +01:00
|
|
|
|
static void
|
|
|
|
|
mct_application_class_init (MctApplicationClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2019-12-19 14:41:17 +01:00
|
|
|
|
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
2019-12-17 16:41:03 +01:00
|
|
|
|
|
|
|
|
|
object_class->constructed = mct_application_constructed;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
object_class->dispose = mct_application_dispose;
|
|
|
|
|
|
2019-12-19 14:41:17 +01:00
|
|
|
|
application_class->activate = mct_application_activate;
|
2020-03-27 23:07:34 +01:00
|
|
|
|
application_class->startup = mct_application_startup;
|
2020-10-19 18:55:47 +02:00
|
|
|
|
application_class->command_line = mct_application_command_line;
|
2020-03-27 23:07:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
about_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
const gchar *authors[] =
|
|
|
|
|
{
|
|
|
|
|
"Philip Withnall <withnall@endlessm.com>",
|
|
|
|
|
"Georges Basile Stavracas Neto <georges@endlessm.com>",
|
|
|
|
|
"Andre Moreira Magalhaes <andre@endlessm.com>",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
gtk_show_about_dialog (mct_application_get_main_window (self),
|
|
|
|
|
"version", VERSION,
|
|
|
|
|
"copyright", _("Copyright © 2019, 2020 Endless Mobile, Inc."),
|
|
|
|
|
"authors", authors,
|
2020-04-20 14:45:28 +02:00
|
|
|
|
/* Translators: this should be "translated" to the
|
|
|
|
|
names of people who have translated Malcontent into
|
|
|
|
|
this language, one per line. */
|
2020-03-27 23:07:34 +01:00
|
|
|
|
"translator-credits", _("translator-credits"),
|
|
|
|
|
"logo-icon-name", "org.freedesktop.MalcontentControl",
|
|
|
|
|
"license-type", GTK_LICENSE_GPL_2_0,
|
|
|
|
|
"wrap-license", TRUE,
|
2020-04-20 14:45:28 +02:00
|
|
|
|
/* Translators: "Malcontent" is the brand name of this
|
|
|
|
|
project, so should not be translated. */
|
2020-03-27 23:07:34 +01:00
|
|
|
|
"website-label", _("Malcontent Website"),
|
|
|
|
|
"website", "https://gitlab.freedesktop.org/pwithnall/malcontent",
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2022-07-08 21:44:48 +02:00
|
|
|
|
on_malcontent_help_shown_finished_cb (GObject *source,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
2020-03-27 23:07:34 +01:00
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
g_autoptr(GError) local_error = NULL;
|
|
|
|
|
|
2022-07-08 21:44:48 +02:00
|
|
|
|
if (!gtk_show_uri_full_finish (mct_application_get_main_window (self),
|
|
|
|
|
result,
|
|
|
|
|
&local_error))
|
2020-03-27 23:07:34 +01:00
|
|
|
|
{
|
|
|
|
|
GtkWidget *dialog = gtk_message_dialog_new (mct_application_get_main_window (self),
|
|
|
|
|
GTK_DIALOG_MODAL,
|
|
|
|
|
GTK_MESSAGE_ERROR,
|
|
|
|
|
GTK_BUTTONS_OK,
|
|
|
|
|
_("The help contents could not be displayed"));
|
|
|
|
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", local_error->message);
|
2022-07-08 21:44:48 +02:00
|
|
|
|
gtk_window_present (GTK_WINDOW (dialog));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-27 23:07:34 +01:00
|
|
|
|
|
2022-07-08 21:44:48 +02:00
|
|
|
|
static void
|
|
|
|
|
help_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
2020-03-27 23:07:34 +01:00
|
|
|
|
|
2022-07-08 21:44:48 +02:00
|
|
|
|
gtk_show_uri_full (mct_application_get_main_window (self),
|
|
|
|
|
"help:malcontent",
|
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
|
NULL,
|
|
|
|
|
on_malcontent_help_shown_finished_cb,
|
|
|
|
|
self);
|
2020-03-27 23:07:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
quit_action_cb (GSimpleAction *action, GVariant *parameters, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
|
|
|
|
|
g_application_quit (G_APPLICATION (self));
|
2019-12-17 16:41:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
static void
|
2020-01-28 15:16:40 +01:00
|
|
|
|
update_main_stack (MctApplication *self)
|
2020-01-10 18:03:20 +01:00
|
|
|
|
{
|
2020-01-28 15:30:26 +01:00
|
|
|
|
gboolean is_user_manager_loaded, is_permission_loaded, has_permission;
|
2020-01-28 15:16:40 +01:00
|
|
|
|
const gchar *new_page_name, *old_page_name;
|
|
|
|
|
GtkWidget *new_focus_widget;
|
2020-01-28 16:07:18 +01:00
|
|
|
|
ActUser *selected_user;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
|
|
|
|
/* The implementation of #ActUserManager guarantees that once is-loaded is
|
|
|
|
|
* true, it is never reset to false. */
|
2020-01-28 15:16:40 +01:00
|
|
|
|
g_object_get (self->user_manager, "is-loaded", &is_user_manager_loaded, NULL);
|
2020-01-28 15:30:26 +01:00
|
|
|
|
is_permission_loaded = (self->permission != NULL || self->permission_error != NULL);
|
|
|
|
|
has_permission = (self->permission != NULL && g_permission_get_allowed (self->permission));
|
2020-01-28 16:07:18 +01:00
|
|
|
|
selected_user = mct_user_selector_get_user (self->user_selector);
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
/* Handle any loading errors (including those from getting the permission). */
|
|
|
|
|
if ((is_user_manager_loaded && act_user_manager_no_service (self->user_manager)) ||
|
|
|
|
|
self->permission_error != NULL)
|
2020-01-10 18:03:20 +01:00
|
|
|
|
{
|
2022-07-08 20:11:30 +02:00
|
|
|
|
adw_status_page_set_title (self->error_page,
|
2021-02-08 23:31:25 +01:00
|
|
|
|
_("Failed to load user data from the system"));
|
2022-07-08 20:11:30 +02:00
|
|
|
|
adw_status_page_set_description (self->error_page,
|
2021-02-08 23:31:25 +01:00
|
|
|
|
_("Please make sure that the AccountsService is installed and enabled."));
|
2020-01-10 18:03:20 +01:00
|
|
|
|
|
|
|
|
|
new_page_name = "error";
|
2020-01-28 15:16:40 +01:00
|
|
|
|
new_focus_widget = NULL;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
}
|
2020-01-28 16:07:18 +01:00
|
|
|
|
else if (is_user_manager_loaded && selected_user == NULL)
|
|
|
|
|
{
|
|
|
|
|
new_page_name = "no-other-users";
|
|
|
|
|
new_focus_widget = GTK_WIDGET (self->user_accounts_panel_button);
|
|
|
|
|
}
|
2020-01-28 15:30:26 +01:00
|
|
|
|
else if (is_permission_loaded && !has_permission)
|
|
|
|
|
{
|
|
|
|
|
gtk_lock_button_set_permission (self->lock_button, self->permission);
|
|
|
|
|
mct_user_controls_set_permission (self->user_controls, self->permission);
|
|
|
|
|
|
|
|
|
|
new_page_name = "unlock";
|
|
|
|
|
new_focus_widget = GTK_WIDGET (self->lock_button);
|
|
|
|
|
}
|
|
|
|
|
else if (is_permission_loaded && is_user_manager_loaded)
|
2020-01-10 18:03:20 +01:00
|
|
|
|
{
|
2020-11-03 17:23:48 +01:00
|
|
|
|
g_autofree gchar *help_label = NULL;
|
|
|
|
|
|
|
|
|
|
/* Translators: Replace the link to commonsensemedia.org with some
|
|
|
|
|
* localised guidance for parents/carers on how to set restrictions on
|
|
|
|
|
* their child/caree in a responsible way which is in keeping with the
|
|
|
|
|
* best practice and culture of the region. If no suitable localised
|
|
|
|
|
* guidance exists, and if the default commonsensemedia.org link is not
|
|
|
|
|
* suitable, please file an issue against malcontent so we can discuss
|
|
|
|
|
* further!
|
|
|
|
|
* https://gitlab.freedesktop.org/pwithnall/malcontent/-/issues/new
|
|
|
|
|
*/
|
|
|
|
|
help_label = g_strdup_printf (_("It’s recommended that restrictions are "
|
|
|
|
|
"set as part of an ongoing conversation "
|
|
|
|
|
"with %s. <a href='https://www.commonsensemedia.org/privacy-and-internet-safety'>"
|
|
|
|
|
"Read guidance</a> on what to consider."),
|
|
|
|
|
act_user_get_real_name (selected_user));
|
2021-02-08 14:27:49 +01:00
|
|
|
|
mct_user_controls_set_description (self->user_controls, help_label);
|
2020-11-03 17:23:48 +01:00
|
|
|
|
|
2020-01-28 16:07:18 +01:00
|
|
|
|
mct_user_controls_set_user (self->user_controls, selected_user);
|
|
|
|
|
|
2020-01-10 18:03:20 +01:00
|
|
|
|
new_page_name = "controls";
|
2021-10-07 17:18:00 +02:00
|
|
|
|
new_focus_widget = GTK_WIDGET (self->user_controls);
|
2020-01-10 18:03:20 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
new_page_name = "loading";
|
2020-01-28 15:16:40 +01:00
|
|
|
|
new_focus_widget = NULL;
|
2020-01-10 18:03:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 15:16:40 +01:00
|
|
|
|
old_page_name = gtk_stack_get_visible_child_name (self->main_stack);
|
2020-01-10 18:03:20 +01:00
|
|
|
|
gtk_stack_set_visible_child_name (self->main_stack, new_page_name);
|
2020-01-28 15:16:40 +01:00
|
|
|
|
|
|
|
|
|
if (new_focus_widget != NULL && !g_str_equal (old_page_name, new_page_name))
|
2022-07-08 15:33:05 +02:00
|
|
|
|
gtk_widget_grab_focus (new_focus_widget);
|
2020-01-28 15:16:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
user_selector_notify_user_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
|
2020-01-28 16:07:18 +01:00
|
|
|
|
update_main_stack (self);
|
2020-01-28 15:16:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
user_manager_notify_is_loaded_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
|
|
|
|
|
update_main_stack (self);
|
2020-01-10 18:03:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 15:30:26 +01:00
|
|
|
|
static void
|
|
|
|
|
permission_new_cb (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
g_autoptr(GPermission) permission = NULL;
|
|
|
|
|
g_autoptr(GError) local_error = NULL;
|
|
|
|
|
|
|
|
|
|
permission = polkit_permission_new_finish (result, &local_error);
|
|
|
|
|
if (permission == NULL)
|
|
|
|
|
{
|
|
|
|
|
g_assert (self->permission_error == NULL);
|
|
|
|
|
self->permission_error = g_steal_pointer (&local_error);
|
|
|
|
|
g_debug ("Error getting permission: %s", self->permission_error->message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_assert (self->permission == NULL);
|
|
|
|
|
self->permission = g_steal_pointer (&permission);
|
|
|
|
|
|
|
|
|
|
g_signal_connect (self->permission, "notify::allowed",
|
|
|
|
|
G_CALLBACK (permission_notify_allowed_cb), self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recalculate the UI. */
|
|
|
|
|
update_main_stack (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
permission_notify_allowed_cb (GObject *obj,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
MctApplication *self = MCT_APPLICATION (user_data);
|
|
|
|
|
|
|
|
|
|
update_main_stack (self);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 16:07:18 +01:00
|
|
|
|
static void
|
|
|
|
|
user_accounts_panel_button_clicked_cb (GtkButton *button,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr(GError) local_error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!g_spawn_command_line_async ("gnome-control-center user-accounts", &local_error))
|
|
|
|
|
{
|
|
|
|
|
g_warning ("Error opening GNOME Control Center: %s",
|
|
|
|
|
local_error->message);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 16:41:03 +01:00
|
|
|
|
/**
|
|
|
|
|
* mct_application_new:
|
|
|
|
|
*
|
|
|
|
|
* Create a new #MctApplication.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer full): a new #MctApplication
|
|
|
|
|
* Since: 0.5.0
|
|
|
|
|
*/
|
|
|
|
|
MctApplication *
|
|
|
|
|
mct_application_new (void)
|
|
|
|
|
{
|
|
|
|
|
return g_object_new (MCT_TYPE_APPLICATION, NULL);
|
|
|
|
|
}
|