[gnome-initial-setup/parental-controls: 7/8] WIP



commit 0c03c9c192d1d9a31ddd1568942b9a6374893e8a
Author: Philip Withnall <withnall endlessm com>
Date:   Wed Feb 5 14:12:40 2020 +0000

    WIP
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 gnome-initial-setup/gis-driver.c                   |  45 +++++++++
 gnome-initial-setup/gis-driver.h                   |   4 +
 gnome-initial-setup/meson.build                    |   1 +
 .../pages/account/gis-account-page-local.c         |  22 +++--
 .../pages/account/gis-account-page.c               |  29 ++++--
 gnome-initial-setup/pages/meson.build              |   2 +-
 .../parental-controls/gis-parental-controls-page.c | 107 +++++++++++++++------
 .../gis-parental-controls-page.ui                  |   4 +-
 .../pages/password/gis-password-page.c             |  11 ++-
 .../pages/password/gis-password-page.ui            |   1 +
 meson.build                                        |   5 +-
 11 files changed, 181 insertions(+), 50 deletions(-)
---
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
index 762cc24..fff43d5 100644
--- a/gnome-initial-setup/gis-driver.c
+++ b/gnome-initial-setup/gis-driver.c
@@ -62,6 +62,7 @@ enum {
   PROP_MODE,
   PROP_USERNAME,
   PROP_SMALL_SCREEN,
+  PROP_FULL_NAME,
   PROP_LAST,
 };
 
@@ -85,6 +86,7 @@ struct _GisDriverPrivate {
 
   gchar *lang_id;
   gchar *username;
+  gchar *full_name;  /* (owned) (nullable) */
 
   GisDriverMode mode;
   UmAccountMode account_mode;
@@ -119,6 +121,7 @@ gis_driver_finalize (GObject *object)
 
   g_free (priv->lang_id);
   g_free (priv->username);
+  g_free (priv->full_name);
   g_free (priv->user_password);
 
   g_clear_object (&priv->user_account);
@@ -248,6 +251,36 @@ gis_driver_get_username (GisDriver *driver)
   GisDriverPrivate *priv = gis_driver_get_instance_private (driver);
   return priv->username;
 }
+
+/* TODO docs */
+void
+gis_driver_set_full_name (GisDriver   *driver,
+                          const gchar *full_name)
+{
+  GisDriverPrivate *priv = gis_driver_get_instance_private (driver);
+  g_return_if_fail (GIS_IS_DRIVER (driver));
+  g_return_if_fail (full_name == NULL ||
+                        g_utf8_validate (full_name, -1, NULL));
+
+  if (g_strcmp0 (priv->full_name, full_name) == 0)
+    return;
+
+  g_free (priv->full_name);
+  priv->full_name = g_strdup (full_name);
+
+  g_object_notify (G_OBJECT (driver), "full-name");
+}
+
+/* TODO docs */
+const gchar *
+gis_driver_get_full_name (GisDriver *driver)
+{
+  GisDriverPrivate *priv = gis_driver_get_instance_private (driver);
+  g_return_val_if_fail (GIS_IS_DRIVER (driver), NULL);
+
+  return priv->full_name;
+}
+
 void
 gis_driver_set_user_permissions (GisDriver   *driver,
                                  ActUser     *user,
@@ -501,6 +534,9 @@ gis_driver_get_property (GObject      *object,
     case PROP_SMALL_SCREEN:
       g_value_set_boolean (value, priv->small_screen);
       break;
+    case PROP_FULL_NAME:
+      g_value_set_string (value, priv->full_name);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -524,6 +560,9 @@ gis_driver_set_property (GObject      *object,
       g_free (priv->username);
       priv->username = g_value_dup_string (value);
       break;
+    case PROP_FULL_NAME:
+      gis_driver_set_full_name (driver, g_value_get_string (value));
+      break;
    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -792,6 +831,12 @@ gis_driver_class_init (GisDriverClass *klass)
                           FALSE,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
+  /* TODO docs */
+  obj_props[PROP_FULL_NAME] =
+    g_param_spec_string ("full-name", "", "",
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
 }
 
diff --git a/gnome-initial-setup/gis-driver.h b/gnome-initial-setup/gis-driver.h
index c0474ca..6571a1d 100644
--- a/gnome-initial-setup/gis-driver.h
+++ b/gnome-initial-setup/gis-driver.h
@@ -103,6 +103,10 @@ void gis_driver_set_username (GisDriver   *driver,
                               const gchar *username);
 const gchar *gis_driver_get_username (GisDriver *driver);
 
+void gis_driver_set_full_name (GisDriver   *driver,
+                               const gchar *full_name);
+const gchar *gis_driver_get_full_name (GisDriver *driver);
+
 gboolean gis_driver_get_gdm_objects (GisDriver        *driver,
                                      GdmGreeter      **greeter,
                                      GdmUserVerifier **user_verifier);
diff --git a/gnome-initial-setup/meson.build b/gnome-initial-setup/meson.build
index 6eaf7a6..cb5cfae 100644
--- a/gnome-initial-setup/meson.build
+++ b/gnome-initial-setup/meson.build
@@ -52,6 +52,7 @@ dependencies = [
     cheese_dep,
     cheese_gtk_dep,
     ibus_dep,
+    libmalcontent_dep,
     libmalcontent_ui_dep,
 ]
 
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.c 
b/gnome-initial-setup/pages/account/gis-account-page-local.c
index e792a62..54c55e5 100644
--- a/gnome-initial-setup/pages/account/gis-account-page-local.c
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.c
@@ -74,7 +74,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (GisAccountPageLocal, gis_account_page_local, GTK_TYP
 
 enum {
   VALIDATION_CHANGED,
-  USER_CREATED,
+  MAIN_USER_CREATED,
+  PARENT_USER_CREATED,
   CONFIRM,
   LAST_SIGNAL,
 };
@@ -553,6 +554,8 @@ local_create_user (GisAccountPageLocal *page)
     /* TODO We just passed these to the constructor! */
     act_user_set_user_name (parent_user, parent_username);
     act_user_set_account_type (parent_user, ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR);
+
+    g_signal_emit (page, signals[PARENT_USER_CREATED], 0, parent_user, "");
   }
 
   /* Now create the main user. */
@@ -567,7 +570,7 @@ local_create_user (GisAccountPageLocal *page)
 
   set_user_avatar (page, main_user);
 
-  g_signal_emit (page, signals[USER_CREATED], 0, main_user, "");
+  g_signal_emit (page, signals[MAIN_USER_CREATED], 0, main_user, "");
 }
 
 static void
@@ -592,9 +595,13 @@ gis_account_page_local_class_init (GisAccountPageLocalClass *klass)
                                               G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
                                               G_TYPE_NONE, 0);
 
-  signals[USER_CREATED] = g_signal_new ("user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
-                                        G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
-                                        G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
+  signals[MAIN_USER_CREATED] = g_signal_new ("main-user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                             G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                             G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
+
+  signals[PARENT_USER_CREATED] = g_signal_new ("parent-user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                               G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                               G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
 
   signals[CONFIRM] = g_signal_new ("confirm", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
                                    G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
@@ -626,12 +633,15 @@ gboolean
 gis_account_page_local_apply (GisAccountPageLocal *local, GisPage *page)
 {
   GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (local);
-  const gchar *username;
+  const gchar *username, *full_name;
   gboolean parental_controls_enabled;
 
   username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->username_combo));
   gis_driver_set_username (GIS_PAGE (page)->driver, username);
 
+  full_name = gtk_entry_get_text (GTK_ENTRY (priv->fullname_entry));
+  gis_driver_set_full_name (GIS_PAGE (page)->driver, full_name);
+
   parental_controls_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(priv->enable_parental_controls_check_button));
   gis_driver_set_parental_controls_enabled (GIS_PAGE (page)->driver, parental_controls_enabled);
 
diff --git a/gnome-initial-setup/pages/account/gis-account-page.c 
b/gnome-initial-setup/pages/account/gis-account-page.c
index e200074..9ab626f 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.c
+++ b/gnome-initial-setup/pages/account/gis-account-page.c
@@ -169,10 +169,10 @@ gis_account_page_shown (GisPage *gis_page)
 }
 
 static void
-on_local_user_created (GtkWidget      *page_local,
-                       ActUser        *user,
-                       char           *password,
-                       GisAccountPage *page)
+on_local_main_user_created (GtkWidget      *page_local,
+                            ActUser        *user,
+                            const gchar    *password,
+                            GisAccountPage *page)
 {
   const gchar *language;
 
@@ -181,8 +181,21 @@ on_local_user_created (GtkWidget      *page_local,
     act_user_set_language (user, language);
 
   gis_driver_set_user_permissions (GIS_PAGE (page)->driver, user, password);
+}
+
+static void
+on_local_parent_user_created (GtkWidget      *page_local,
+                              ActUser        *user,
+                              const gchar    *password,
+                              GisAccountPage *page)
+{
+  const gchar *language;
+
+  language = gis_driver_get_user_language (GIS_PAGE (page)->driver);
+  if (language)
+    act_user_set_language (user, language);
 
-  /* TODO may need to set the parental controls here */
+  gis_driver_set_parent_permissions (GIS_PAGE (page)->driver, user, password);
 }
 
 static void
@@ -234,8 +247,10 @@ gis_account_page_constructed (GObject *object)
 
   g_signal_connect (priv->page_local, "validation-changed",
                     G_CALLBACK (on_validation_changed), page);
-  g_signal_connect (priv->page_local, "user-created",
-                    G_CALLBACK (on_local_user_created), page);
+  g_signal_connect (priv->page_local, "main-user-created",
+                    G_CALLBACK (on_local_main_user_created), page);
+  g_signal_connect (priv->page_local, "parent-user-created",
+                    G_CALLBACK (on_local_parent_user_created), page);
   g_signal_connect (priv->page_local, "confirm",
                     G_CALLBACK (on_local_page_confirmed), page);
 
diff --git a/gnome-initial-setup/pages/meson.build b/gnome-initial-setup/pages/meson.build
index dbd28a5..7238383 100644
--- a/gnome-initial-setup/pages/meson.build
+++ b/gnome-initial-setup/pages/meson.build
@@ -10,7 +10,7 @@ pages = [
    'summary',
 ]
 
-if libmalcontent_ui_dep.found()
+if libmalcontent_dep.found() and libmalcontent_ui_dep.found()
   pages += 'parental-controls'
 endif
 
diff --git a/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.c 
b/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.c
index 2e4c3f8..95be685 100644
--- a/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.c
+++ b/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.c
@@ -40,46 +40,77 @@ struct _GisParentalControlsPage
 {
   GisPage parent_instance;
 
+  GtkWidget *header;
   GtkWidget *user_controls;
 };
 
 G_DEFINE_TYPE (GisParentalControlsPage, gis_parental_controls_page, GIS_TYPE_PAGE)
 
-static gboolean
-page_validate (GisParentalControlsPage *page)
-{
-  /* TODO */
-}
-
 static void
-update_page_validation (GisParentalControlsPage *page)
-{
-  gis_page_set_complete (GIS_PAGE (page), page_validate (page));
-}
-
-static gboolean
-gis_parental_controls_page_apply (GisPage      *gis_page,
-                                  GCancellable *cancellable)
+gis_parental_controls_page_save_data (GisPage *gis_page)
 {
   GisParentalControlsPage *page = GIS_PARENTAL_CONTROLS_PAGE (gis_page);
-
-  /* TODO */
+  g_autoptr(GDBusConnection) system_bus = NULL;
+  g_autoptr(MctManager) manager = NULL;
+  g_auto(MctAppFilterBuilder) builder = MCT_APP_FILTER_BUILDER_INIT ();
+  g_autoptr(MctAppFilter) app_filter = NULL;
+  g_autoptr(GError) local_error = NULL;
+  ActUser *main_user;
+
+  /* The parent and child users are created by the #GisAccountPage earlier in
+   * the save_data() process. We now need to set the parental controls on the
+   * child user. */
+  gis_driver_get_user_permissions (gis_page->driver, &main_user, NULL);
+
+  mct_user_controls_build_app_filter (MCT_USER_CONTROLS (page->user_controls), &builder);
+  app_filter = mct_app_filter_builder_end (&builder);
+
+  /* FIXME: should become asynchronous */
+  system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error);
+  if (system_bus == NULL)
+    {
+      g_warning ("Error getting system bus while setting up parental controls: %s", local_error->message);
+      return;
+    }
+
+  manager = mct_manager_new (system_bus);
+  mct_manager_set_app_filter (manager,
+                              act_user_get_uid (main_user),
+                              app_filter,
+                              MCT_MANAGER_SET_VALUE_FLAGS_NONE,
+                              NULL,
+                              &local_error);
+
+  if (local_error != NULL)
+    {
+      g_warning ("Error setting parental controls: %s", local_error->message);
+      return;
+    }
 }
 
 static void
-gis_parental_controls_page_save_data (GisPage *gis_page)
+gis_parental_controls_page_shown (GisPage *gis_page)
 {
   GisParentalControlsPage *page = GIS_PARENTAL_CONTROLS_PAGE (gis_page);
 
-  /* TODO: create the user and set the parental controls */
+  gtk_widget_grab_focus (page->user_controls);
 }
 
 static void
-gis_parental_controls_page_shown (GisPage *gis_page)
+update_header (GisParentalControlsPage *page)
 {
-  GisParentalControlsPage *page = GIS_PARENTAL_CONTROLS_PAGE (gis_page);
-
-  /* TODO */
+  g_autofree gchar *title = NULL;
+  const gchar *subtitle;
+
+  /* Translators: The placeholder is the user’s full name. */
+  title = g_strdup_printf (_("Parental Controls for %s"),
+                           gis_driver_get_full_name (GIS_PAGE (page)->driver));
+  subtitle = _("TODO blasd farsd hngh wuf");
+
+  g_object_set (G_OBJECT (page->header),
+                "title", title,
+                "subtitle", subtitle,
+                NULL);
 }
 
 static void
@@ -87,6 +118,8 @@ gis_parental_controls_page_constructed (GObject *object)
 {
   GisParentalControlsPage *page = GIS_PARENTAL_CONTROLS_PAGE (object);
   g_autoptr(GPermission) permission = NULL;
+  g_auto(MctAppFilterBuilder) builder = MCT_APP_FILTER_BUILDER_INIT ();
+  g_autoptr(MctAppFilter) app_filter = NULL;
 
   G_OBJECT_CLASS (gis_parental_controls_page_parent_class)->constructed (object);
 
@@ -94,23 +127,41 @@ gis_parental_controls_page_constructed (GObject *object)
   g_signal_connect (priv->page_local, "validation-changed",
                     G_CALLBACK (on_validation_changed), page); */
 
-  update_page_validation (page);
+  /* No validation needed. */
+  gis_page_set_complete (GIS_PAGE (page), TRUE);
+
+  /* Set up the user controls. We can’t set #MctUserControls:user because
+   * there’s no way to represent a not-yet-created user using an #ActUser. */
+  mct_user_controls_set_user_account_type (MCT_USER_CONTROLS (page->user_controls),
+                                           ACT_USER_ACCOUNT_TYPE_STANDARD);
+  mct_user_controls_set_user_locale (MCT_USER_CONTROLS (page->user_controls),
+                                     gis_driver_get_user_language (GIS_PAGE (page)->driver));
+  mct_user_controls_set_user_display_name (MCT_USER_CONTROLS (page->user_controls),
+                                           gis_driver_get_full_name (GIS_PAGE (page)->driver));
 
-  //mct_user_controls_set_user (MCT_USER_CONTROLS (page->user_controls), selected_user);
+  app_filter = mct_app_filter_builder_end (&builder);
+  mct_user_controls_set_app_filter (MCT_USER_CONTROLS (page->user_controls), app_filter);
 
   /* The gnome-initial-setup user should always be allowed to set parental
    * controls. */
   permission = g_simple_permission_new (TRUE);
-  // TODO makes controls disappear mct_user_controls_set_permission (MCT_USER_CONTROLS 
(page->user_controls), permission);
+  mct_user_controls_set_permission (MCT_USER_CONTROLS (page->user_controls), permission);
+
+  update_header (page);
 
   /* TODO is this necessary? */
   gtk_widget_show (GTK_WIDGET (page));
 }
 
 static void
-gis_parental_controls_page_locale_changed (GisPage *page)
+gis_parental_controls_page_locale_changed (GisPage *gis_page)
 {
-  gis_page_set_title (GIS_PAGE (page), _("Parental Controls"));
+  GisParentalControlsPage *page = GIS_PARENTAL_CONTROLS_PAGE (gis_page);
+
+  gis_page_set_title (gis_page, _("Parental Controls"));
+
+  /* TODO */
+  update_header (page);
 }
 
 static void
@@ -124,12 +175,12 @@ gis_parental_controls_page_class_init (GisParentalControlsPageClass *klass)
 
   page_class->page_id = PAGE_ID;
   page_class->locale_changed = gis_parental_controls_page_locale_changed;
-  page_class->apply = gis_parental_controls_page_apply;
   page_class->save_data = gis_parental_controls_page_save_data;
   page_class->shown = gis_parental_controls_page_shown;
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/initial-setup/gis-parental-controls-page.ui");
 
+  gtk_widget_class_bind_template_child (widget_class, GisParentalControlsPage, header);
   gtk_widget_class_bind_template_child (widget_class, GisParentalControlsPage, user_controls);
 }
 
diff --git a/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.ui 
b/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.ui
index e27bb3d..dee401b 100644
--- a/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.ui
+++ b/gnome-initial-setup/pages/parental-controls/gis-parental-controls-page.ui
@@ -12,9 +12,7 @@
           <object class="GisPageHeader" id="header">
             <property name="visible">True</property>
             <property name="margin-top">24</property>
-            <!-- TODO title and subtitle are set in code, so are not set here -->
-            <property name="title">Parental Controls for Kimberley</property>
-            <property name="subtitle">TODO blasd farsd hngh wuf</property>
+            <!-- title and subtitle are set in code, so are not set here -->
             <!-- TODO: Would be good to use the user avatar instead of an icon -->
             <property name="icon-name">dialog-password-symbolic</property>
             <property name="show-icon" bind-source="GisParentalControlsPage" bind-property="small-screen" 
bind-flags="invert-boolean|sync-create"/>
diff --git a/gnome-initial-setup/pages/password/gis-password-page.c 
b/gnome-initial-setup/pages/password/gis-password-page.c
index 7bd4b7c..48b6052 100644
--- a/gnome-initial-setup/pages/password/gis-password-page.c
+++ b/gnome-initial-setup/pages/password/gis-password-page.c
@@ -69,17 +69,20 @@ static void
 update_header (GisPasswordPage *page)
 {
   GisPasswordPagePrivate *priv = gis_password_page_get_instance_private (page);
-  const gchar *title, *subtitle;
+  g_autofree gchar *title = NULL;
+  const gchar *subtitle;
 
   if (!priv->parent_mode)
     {
-      title = _("Set a User Password");
+      /* Translators: The placeholder is for the user’s full name. */
+      title = g_strdup_printf (_("Set a Password for %s"),
+                               gis_driver_get_full_name (GIS_PAGE (page)->driver));
       subtitle = _("Be careful not to lose your password.");
     }
   else
     {
-      title = _("Set a Parent Password");
-      subtitle = _("This password will control access to the parental controls for the child’s user 
account.");
+      title = g_strdup (_("Set a Parent Password"));
+      subtitle = _("This password will control access to the parental controls for the system.");
     }
 
   g_object_set (G_OBJECT (priv->header),
diff --git a/gnome-initial-setup/pages/password/gis-password-page.ui 
b/gnome-initial-setup/pages/password/gis-password-page.ui
index b21010c..b773036 100644
--- a/gnome-initial-setup/pages/password/gis-password-page.ui
+++ b/gnome-initial-setup/pages/password/gis-password-page.ui
@@ -14,6 +14,7 @@
             <property name="visible">True</property>
             <property name="margin_top">24</property>
             <!-- title and subtitle are set in code, so are not set here -->
+            <!-- TODO: Can we get a different icon for the parent password? -->
             <property name="icon_name">dialog-password-symbolic</property>
             <property name="show_icon" bind-source="GisPasswordPage" bind-property="small-screen" 
bind-flags="invert-boolean|sync-create"/>
           </object>
diff --git a/meson.build b/meson.build
index 3bbb05d..f6e4be5 100644
--- a/meson.build
+++ b/meson.build
@@ -60,10 +60,13 @@ ibus_dep = dependency ('ibus-1.0',
 conf.set('HAVE_IBUS', ibus_dep.found())
 
 # Needed for the parental controls pages
+libmalcontent_dep = dependency ('malcontent-0',
+                                version: '>= 0.5.0',
+                                required: get_option('parental_controls'))
 libmalcontent_ui_dep = dependency ('malcontent-ui-0',
                                    version: '>= 0.5.0',
                                    required: get_option('parental_controls'))
-conf.set('HAVE_PARENTAL_CONTROLS', libmalcontent_ui_dep.found())
+conf.set('HAVE_PARENTAL_CONTROLS', libmalcontent_dep.found() and libmalcontent_ui_dep.found())
 
 configure_file(output: 'config.h',
                configuration: conf)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]