/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2013 Red Hat
*
* 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 .
*
* Written by:
* Jasper St. Pierre
*/
#include "config.h"
#include "gis-welcome-widget.h"
#include
#include
#include
#include "cc-common-language.h"
struct _GisWelcomeWidgetPrivate
{
AdwCarousel *carousel;
GHashTable *translation_widgets; /* (element-type owned utf8 unowned GtkWidget) (owned) */
guint timeout_id;
};
typedef struct _GisWelcomeWidgetPrivate GisWelcomeWidgetPrivate;
#define TIMEOUT 5
G_DEFINE_TYPE_WITH_PRIVATE (GisWelcomeWidget, gis_welcome_widget, ADW_TYPE_BIN);
static gboolean
advance_stack (gpointer user_data)
{
GisWelcomeWidget *widget = user_data;
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
GtkWidget *child;
unsigned int next_page;
unsigned int n_pages;
double current_page;
n_pages = adw_carousel_get_n_pages (priv->carousel);
if (n_pages == 0)
goto out;
current_page = ceil (adw_carousel_get_position (priv->carousel));
next_page = ((int) current_page + 1) % n_pages;
child = gtk_widget_get_first_child (GTK_WIDGET (priv->carousel));
while (next_page-- > 0)
child = gtk_widget_get_next_sibling (child);
adw_carousel_scroll_to (priv->carousel, child, TRUE);
out:
return G_SOURCE_CONTINUE;
}
static void
gis_welcome_widget_start (GisWelcomeWidget *widget)
{
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
if (priv->timeout_id > 0)
return;
priv->timeout_id = g_timeout_add_seconds (5, advance_stack, widget);
}
static void
gis_welcome_widget_stop (GisWelcomeWidget *widget)
{
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
if (priv->timeout_id == 0)
return;
g_source_remove (priv->timeout_id);
priv->timeout_id = 0;
}
static void
gis_welcome_widget_map (GtkWidget *widget)
{
GTK_WIDGET_CLASS (gis_welcome_widget_parent_class)->map (widget);
gis_welcome_widget_start (GIS_WELCOME_WIDGET (widget));
}
static void
gis_welcome_widget_unmap (GtkWidget *widget)
{
GTK_WIDGET_CLASS (gis_welcome_widget_parent_class)->unmap (widget);
gis_welcome_widget_stop (GIS_WELCOME_WIDGET (widget));
}
static const char *
welcome (const char *locale_id)
{
locale_t locale;
locale_t old_locale;
const char *welcome;
locale = newlocale (LC_MESSAGES_MASK, locale_id, (locale_t) 0);
if (locale == (locale_t) 0)
{
if (errno == ENOENT)
g_debug ("Failed to create locale %s: %s", locale_id, g_strerror (errno));
else
g_warning ("Failed to create locale %s: %s", locale_id, g_strerror (errno));
return "Welcome!";
}
old_locale = uselocale (locale);
/* Translators: This is meant to be a warm, engaging welcome message,
* like greeting somebody at the door. If the exclamation mark is not
* suitable for this in your language you may replace it.
*/
welcome = _("Welcome!");
uselocale (old_locale);
freelocale (locale);
return welcome;
}
static GtkWidget *
big_label (const char *text)
{
GtkWidget *label = gtk_label_new (text);
gtk_style_context_add_class (gtk_widget_get_style_context (label), "title-1");
return label;
}
static void
fill_carousel (GisWelcomeWidget *widget)
{
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
g_autoptr(GHashTable) initial = cc_common_language_get_initial_languages ();
GHashTableIter iter;
gpointer key, value;
g_autoptr(GHashTable) added_translations = NULL;
added_translations = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_iter_init (&iter, initial);
while (g_hash_table_iter_next (&iter, &key, &value))
{
const char *locale_id = key;
const char *text;
GtkWidget *label;
if (!cc_common_language_has_font (locale_id))
continue;
text = welcome (locale_id);
label = g_hash_table_lookup (added_translations, text);
if (label == NULL) {
label = big_label (text);
adw_carousel_append (priv->carousel, label);
g_hash_table_insert (added_translations, (gpointer) text, label);
}
g_hash_table_insert (priv->translation_widgets, g_strdup (locale_id), label);
}
}
static void
gis_welcome_widget_constructed (GObject *object)
{
G_OBJECT_CLASS (gis_welcome_widget_parent_class)->constructed (object);
fill_carousel (GIS_WELCOME_WIDGET (object));
}
static void
gis_welcome_widget_dispose (GObject *object)
{
GisWelcomeWidget *widget = GIS_WELCOME_WIDGET (object);
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
g_clear_pointer (&priv->translation_widgets, g_hash_table_unref);
G_OBJECT_CLASS (gis_welcome_widget_parent_class)->dispose (object);
}
static void
gis_welcome_widget_class_init (GisWelcomeWidgetClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/initial-setup/gis-welcome-widget.ui");
gtk_widget_class_bind_template_child_private (widget_class, GisWelcomeWidget, carousel);
object_class->constructed = gis_welcome_widget_constructed;
object_class->dispose = gis_welcome_widget_dispose;
widget_class->map = gis_welcome_widget_map;
widget_class->unmap = gis_welcome_widget_unmap;
}
static void
gis_welcome_widget_init (GisWelcomeWidget *widget)
{
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
priv->translation_widgets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
gtk_widget_init_template (GTK_WIDGET (widget));
}
void
gis_welcome_widget_show_locale (GisWelcomeWidget *widget,
const char *locale_id)
{
GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget);
GtkWidget *label;
/* Restart the widget to reset the timer. */
gis_welcome_widget_stop (widget);
gis_welcome_widget_start (widget);
label = g_hash_table_lookup (priv->translation_widgets, locale_id);
if (label)
adw_carousel_scroll_to (priv->carousel, label, FALSE);
}