/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright © 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti
* Copyright © 2003, 2004, 2005 Christian Persch
* Copyright © 2010, 2012 Igalia S.L.
*
* This file is part of Epiphany.
*
* Epiphany 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.
*
* Epiphany 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 Epiphany. If not, see .
*/
#include "config.h"
#include "ephy-lockdown.h"
#include "ephy-action-helper.h"
#include "ephy-debug.h"
#include "ephy-embed-container.h"
#include "ephy-embed-shell.h"
#include "ephy-embed-utils.h"
#include "ephy-location-controller.h"
#include "ephy-prefs.h"
#include "ephy-settings.h"
#include "ephy-shell.h"
#include "ephy-window.h"
#include
#define LOCKDOWN_FLAG 1 << 8
struct _EphyLockdown {
GObject parent_instance;
};
G_DEFINE_TYPE (EphyLockdown, ephy_lockdown, G_TYPE_OBJECT)
static void
arbitrary_url_cb (GSettings *settings,
const char *key,
EphyWindow *window)
{
EphyEmbed *embed;
const char *address;
/* Restore the real web page address when disabling entry */
if (g_settings_get_boolean (settings, key)) {
embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
/* embed is NULL on startup */
if (embed == NULL)
return;
address = ephy_web_view_get_display_address (ephy_embed_get_web_view (embed));
ephy_window_set_location (window, address);
ephy_web_view_set_typed_address (ephy_embed_get_web_view (embed), NULL);
}
}
static void
fullscreen_cb (GSettings *settings,
const char *key,
EphyWindow *window)
{
if (g_settings_get_boolean (settings, key))
gtk_window_fullscreen (GTK_WINDOW (window));
else
gtk_window_unfullscreen (GTK_WINDOW (window));
}
typedef struct {
const char *key;
const char *action;
const char *prop;
} BindAction;
static const BindAction app_actions[] = {
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "new-window", "enabled" },
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "new-incognito", "enabled" },
};
static const BindAction app_mode_app_actions[] = {
{ EPHY_PREFS_LOCKDOWN_HISTORY, "history", "enabled" }
};
static const BindAction window_actions[] = {
{ EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, "location", "enabled"},
{ EPHY_PREFS_LOCKDOWN_BOOKMARK_EDITING, "bookmark-page", "enabled" },
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "fullscreen", "enabled" },
{ EPHY_PREFS_LOCKDOWN_PRINTING, "print", "enabled" },
{ EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "save-as", "enabled" }
};
static const BindAction popup_actions[] = {
{ EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "download-link-as", "enabled" },
{ EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "save-image-as", "enabled" },
{ EPHY_PREFS_LOCKDOWN_BOOKMARK_EDITING, "context-bookmark-page", "enabled" },
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "open-link-in-new-window", "enabled" }
};
static const BindAction tab_actions[] = {
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "detach", "enabled" }
};
static const BindAction toolbar_actions[] = {
{ EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-back", "enabled" },
{ EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-forward", "enabled" }
};
static gboolean
sensitive_get_mapping (GValue *value,
GVariant *variant,
gpointer data)
{
GAction *action;
gboolean active, before, after;
action = G_ACTION (data);
active = g_variant_get_boolean (variant);
before = g_action_get_enabled (action);
ephy_action_change_sensitivity_flags (G_SIMPLE_ACTION (action), LOCKDOWN_FLAG, active);
after = g_action_get_enabled (action);
/* Set (GAction::enabled) to the value in GSettings _only if_
* the LOCKDOWN_FLAG had some real effect in the GAction */
g_value_set_boolean (value, (before != after) ? after : before);
return TRUE;
}
static void
bind_settings_and_actions (GSettings *settings,
GActionGroup *action_group,
const BindAction *actions,
int actions_n)
{
int i;
for (i = 0; i < actions_n; i++) {
GAction *action;
action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
actions[i].action);
g_assert (action);
/* We need a custom get_mapping for 'enabled'
* properties, see usage of
* ephy_action_change_sensitivity_flags in
* ephy-window.c. */
g_settings_bind_with_mapping (settings, actions[i].key,
action, actions[i].prop,
G_SETTINGS_BIND_GET,
sensitive_get_mapping,
NULL,
action, NULL);
}
}
static void
bind_location_controller (GSettings *settings,
EphyLocationController *controller)
{
g_settings_bind (settings, EPHY_PREFS_LOCKDOWN_ARBITRARY_URL,
controller, "editable",
G_SETTINGS_BIND_GET |
G_SETTINGS_BIND_INVERT_BOOLEAN);
}
static void
window_added_cb (GtkApplication *application,
GtkWindow *window,
EphyLockdown *lockdown)
{
GActionGroup *action_group;
EphyEmbedShellMode mode;
GAction *action;
GSettings *settings;
EphyLocationController *location_controller;
if (!EPHY_IS_WINDOW (window))
return;
g_signal_connect (EPHY_SETTINGS_LOCKDOWN,
"changed::" EPHY_PREFS_LOCKDOWN_FULLSCREEN,
G_CALLBACK (fullscreen_cb), window);
g_signal_connect (EPHY_SETTINGS_LOCKDOWN,
"changed::" EPHY_PREFS_LOCKDOWN_ARBITRARY_URL,
G_CALLBACK (arbitrary_url_cb), window);
/* Trigger an initial state on these elements. */
fullscreen_cb (EPHY_SETTINGS_LOCKDOWN,
EPHY_PREFS_LOCKDOWN_FULLSCREEN, EPHY_WINDOW (window));
arbitrary_url_cb (EPHY_SETTINGS_LOCKDOWN,
EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, EPHY_WINDOW (window));
mode = ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (application));
action_group = G_ACTION_GROUP (G_APPLICATION (application));
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION) {
/* These actions do not exist in application mode. */
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group, app_actions,
G_N_ELEMENTS (app_actions));
}
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group, app_mode_app_actions,
G_N_ELEMENTS (app_mode_app_actions));
action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"win");
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group,
window_actions,
G_N_ELEMENTS (window_actions));
action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"tab");
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group,
tab_actions,
G_N_ELEMENTS (tab_actions));
action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"toolbar");
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group,
toolbar_actions,
G_N_ELEMENTS (toolbar_actions));
action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"popup");
bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
action_group, popup_actions,
G_N_ELEMENTS (popup_actions));
action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
"set-image-as-background");
settings = ephy_settings_get ("org.gnome.desktop.background");
g_settings_bind_writable (settings, "picture-filename",
action, "enabled", FALSE);
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION &&
mode != EPHY_EMBED_SHELL_MODE_AUTOMATION) {
location_controller = ephy_window_get_location_controller (EPHY_WINDOW (window));
bind_location_controller (EPHY_SETTINGS_LOCKDOWN, location_controller);
}
}
static void
ephy_lockdown_init (EphyLockdown *lockdown)
{
EphyShell *shell;
LOG ("EphyLockdown initialising");
shell = ephy_shell_get_default ();
g_signal_connect (shell, "window-added",
G_CALLBACK (window_added_cb), lockdown);
}
static void
ephy_lockdown_class_init (EphyLockdownClass *klass)
{
}