Blame src/dh-tab.c

Packit 116408
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
Packit 116408
/*
Packit 116408
 * Copyright (C) 2018 Sébastien Wilmet <swilmet@gnome.org>
Packit 116408
 *
Packit 116408
 * This program is free software; you can redistribute it and/or
Packit 116408
 * modify it under the terms of the GNU General Public License as
Packit 116408
 * published by the Free Software Foundation; either version 2 of the
Packit 116408
 * License, or (at your option) any later version.
Packit 116408
 *
Packit 116408
 * This program is distributed in the hope that it will be useful,
Packit 116408
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 116408
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 116408
 * General Public License for more details.
Packit 116408
 *
Packit 116408
 * You should have received a copy of the GNU General Public License
Packit 116408
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 116408
 */
Packit 116408
Packit 116408
#include "dh-tab.h"
Packit 116408
#include <glib/gi18n.h>
Packit 116408
#include "tepl-info-bar.h"
Packit 116408
Packit 116408
/* A DhWebView with a possible TeplInfoBar on top. */
Packit 116408
Packit 116408
struct _DhTabPrivate {
Packit 116408
        TeplInfoBar *info_bar;
Packit 116408
        DhWebView *web_view;
Packit 116408
};
Packit 116408
Packit 116408
G_DEFINE_TYPE_WITH_PRIVATE (DhTab, dh_tab, GTK_TYPE_GRID)
Packit 116408
Packit 116408
static void
Packit 116408
dh_tab_dispose (GObject *object)
Packit 116408
{
Packit 116408
        DhTab *tab = DH_TAB (object);
Packit 116408
Packit 116408
        tab->priv->info_bar = NULL;
Packit 116408
        tab->priv->web_view = NULL;
Packit 116408
Packit 116408
        G_OBJECT_CLASS (dh_tab_parent_class)->dispose (object);
Packit 116408
}
Packit 116408
Packit 116408
static void
Packit 116408
dh_tab_class_init (DhTabClass *klass)
Packit 116408
{
Packit 116408
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit 116408
Packit 116408
        object_class->dispose = dh_tab_dispose;
Packit 116408
}
Packit 116408
Packit 116408
static gboolean
Packit 116408
web_view_load_failed_cb (WebKitWebView   *web_view,
Packit 116408
                         WebKitLoadEvent  load_event,
Packit 116408
                         const gchar     *failing_uri,
Packit 116408
                         GError          *error,
Packit 116408
                         DhTab           *tab)
Packit 116408
{
Packit 116408
        /* Ignore cancellation errors, which happen when typing fast in the
Packit 116408
         * search entry.
Packit 116408
         */
Packit 116408
        if (g_error_matches (error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED))
Packit 116408
                return GDK_EVENT_STOP;
Packit 116408
Packit 116408
        if (tab->priv->info_bar != NULL)
Packit 116408
                gtk_widget_destroy (GTK_WIDGET (tab->priv->info_bar));
Packit 116408
Packit 116408
        tab->priv->info_bar = tepl_info_bar_new_simple (GTK_MESSAGE_ERROR,
Packit 116408
                                                        _("Error opening the requested link."),
Packit 116408
                                                        error->message);
Packit 116408
        tepl_info_bar_add_close_button (tab->priv->info_bar);
Packit 116408
Packit 116408
        g_signal_connect (tab->priv->info_bar,
Packit 116408
                          "destroy",
Packit 116408
                          G_CALLBACK (gtk_widget_destroyed),
Packit 116408
                          &tab->priv->info_bar);
Packit 116408
Packit 116408
        gtk_grid_attach_next_to (GTK_GRID (tab),
Packit 116408
                                 GTK_WIDGET (tab->priv->info_bar),
Packit 116408
                                 GTK_WIDGET (tab->priv->web_view),
Packit 116408
                                 GTK_POS_TOP,
Packit 116408
                                 1, 1);
Packit 116408
Packit 116408
        gtk_widget_show (GTK_WIDGET (tab->priv->info_bar));
Packit 116408
Packit 116408
        return GDK_EVENT_STOP;
Packit 116408
}
Packit 116408
Packit 116408
static gboolean
Packit 116408
web_view_decide_policy_cb (WebKitWebView            *web_view,
Packit 116408
                           WebKitPolicyDecision     *decision,
Packit 116408
                           WebKitPolicyDecisionType  decision_type,
Packit 116408
                           DhTab                    *tab)
Packit 116408
{
Packit 116408
        if (decision_type == WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION &&
Packit 116408
            tab->priv->info_bar != NULL) {
Packit 116408
                /* The error is no longer relevant. Do it here, not in
Packit 116408
                 * ::load-changed, so that it works when clicking on a link to
Packit 116408
                 * an anchor inside the same page too, not only when loading a
Packit 116408
                 * different page.
Packit 116408
                 */
Packit 116408
                gtk_widget_destroy (GTK_WIDGET (tab->priv->info_bar));
Packit 116408
        }
Packit 116408
Packit 116408
        return GDK_EVENT_PROPAGATE;
Packit 116408
}
Packit 116408
Packit 116408
static void
Packit 116408
dh_tab_init (DhTab *tab)
Packit 116408
{
Packit 116408
        tab->priv = dh_tab_get_instance_private (tab);
Packit 116408
Packit 116408
        gtk_orientable_set_orientation (GTK_ORIENTABLE (tab), GTK_ORIENTATION_VERTICAL);
Packit 116408
Packit 116408
        tab->priv->web_view = dh_web_view_new ();
Packit 116408
        gtk_widget_show (GTK_WIDGET (tab->priv->web_view));
Packit 116408
        gtk_container_add (GTK_CONTAINER (tab), GTK_WIDGET (tab->priv->web_view));
Packit 116408
Packit 116408
        g_signal_connect (tab->priv->web_view,
Packit 116408
                          "load-failed",
Packit 116408
                          G_CALLBACK (web_view_load_failed_cb),
Packit 116408
                          tab);
Packit 116408
Packit 116408
        /* Other ::decide-policy signal handlers that return GDK_EVENT_STOP must
Packit 116408
         * be connected *after* this one. This code relies on the fact that
Packit 116408
         * GObject executes the handlers in the same order than the connection
Packit 116408
         * order (for all the handlers belonging to the same emission stage).
Packit 116408
         */
Packit 116408
        g_signal_connect (tab->priv->web_view,
Packit 116408
                          "decide-policy",
Packit 116408
                          G_CALLBACK (web_view_decide_policy_cb),
Packit 116408
                          tab);
Packit 116408
}
Packit 116408
Packit 116408
DhTab *
Packit 116408
dh_tab_new (void)
Packit 116408
{
Packit 116408
        return g_object_new (DH_TYPE_TAB, NULL);
Packit 116408
}
Packit 116408
Packit 116408
DhWebView *
Packit 116408
dh_tab_get_web_view (DhTab *tab)
Packit 116408
{
Packit 116408
        g_return_val_if_fail (DH_IS_TAB (tab), NULL);
Packit 116408
Packit 116408
        return tab->priv->web_view;
Packit 116408
}